/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { lodash } from "./lodash/lodash.js";
import {ONE_KB, TEN_kB, ONE_KB_NUMBER_STRING} from "./data.js";

// Array -> 64
function chunk_Test() {
    const source = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.chunk(source, 3)
    }
    let endTime = Date.now();
    if (result.length != 3) {
        throw 'Array.chunk error'
    }
    print(`lodash_chunk: ${endTime - startTime} ms`)
}

function compact_Test() {
    const source = ['apple', 1, '', 2, 'e', 3, false]
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.compact(source)
    }
    let endTime = Date.now();
    if (result.length != 5) {
        throw 'Array.compact error'
    }
    print(`lodash_compact: ${endTime - startTime} ms`)
}

function concat_Test() {
    const source = [1, 2, 3, 4, 5]
    const source1 = 'apple'
    const source2 = ['a', 'b', 'c', 'd', 'e']
    const source3 = new String('123')
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.concat(source, source1, source2, source3)
    }
    let endTime = Date.now();
    if (result.length != 12) {
        throw 'Array.concat error'
    }
    print(`lodash_concat: ${endTime - startTime} ms`)
}

function difference_Test() {
    const source = [1, 2, 3, 4, 5]
    const source1 = [1, 3, 5, 7, 9]
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.difference(source, source1)
    }
    let endTime = Date.now();
    if (result.length != 2) {
        throw 'Array.difference error'
    }
    print(`lodash_difference: ${endTime - startTime} ms`)
}

function differenceBy_Test() {
    const source = [2.1, 1.2, 5.6]
    const source1 = [2.3, 3.4, 7.8]
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.differenceBy(source, source1, Math.floor)
    }
    let endTime = Date.now();
    if (result.length != 2) {
        throw 'Array.differenceBy error'
    }
    print(`lodash_differenceBy: ${endTime - startTime} ms`)
}

function differenceWith_Test() {
    const source = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
    const source1 = [{ 'x': 1, 'y': 2 }]
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.differenceWith(source, source1, lodash.isEqual)
    }
    let endTime = Date.now();
    if (result.length != 1) {
        throw 'Array.differenceBy error'
    }
    print(`lodash_differenceWith: ${endTime - startTime} ms`)
}

function drop_Test() {
    const source = [1, 2, 3, 4, 5, '6', 7, 8, 9, '10']
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.drop(source, 3)
    }
    let endTime = Date.now();
    if (result.length != 7) {
        throw 'Array.drop error'
    }
    print(`lodash_drop: ${endTime - startTime} ms`)
}

function dropRight_Test() {
    const source = [1, 2, 3, 4, 5, '6', 7, 8, 9, '10']
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.dropRight(source, 7)
    }
    let endTime = Date.now();
    if (result.length != 3) {
        throw 'Array.dropRight error'
    }
    print(`lodash_dropRight: ${endTime - startTime} ms`)
}

function dropRightWhile_Test() {
    const source = [
        { 'user': 'barney', 'active': true },
        { 'user': 'fred', 'active': false },
        { 'user': 'pebbles', 'active': false }
    ];
    const source1 = ['active', false]
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.dropRightWhile(source, source1)
    }
    let endTime = Date.now();
    if (result.length != 1) {
        throw 'Array.dropRightWhile error'
    }
    print(`lodash_dropRightWhile: ${endTime - startTime} ms`)
}

function dropWhile_Test() {
    const source = [
        { 'user': 'barney', 'active': false },
        { 'user': 'fred', 'active': false },
        { 'user': 'pebbles', 'active': true }
    ];
    const source1 = { 'user': 'barney', 'active': false }
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.dropWhile(source, source1)
    }
    let endTime = Date.now();
    if (result.length != 2) {
        throw 'Array.dropWhile error'
    }
    print(`lodash_dropWhile: ${endTime - startTime} ms`)
}

function fill_Test() {
    const source = [1, 2, 3, 4, 5, '6', 7, 8, 9, '10']
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.fill(source, 'apple', 1, 4)
    }
    let endTime = Date.now();
    if (result[2] != 'apple') {
        throw 'Array.fill error'
    }
    print(`lodash_fill: ${endTime - startTime} ms`)
}

function findIndex_Test() {
    const source = [
        { 'user': 'barney', 'active': false },
        { 'user': 'fred', 'active': false },
        { 'user': 'pebbles', 'active': true }
    ];
    const source1 = { 'user': 'pebbles', 'active': true }
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.findIndex(source, source1)
    }
    let endTime = Date.now();
    if (result != 2) {
        throw 'Array.findIndex error'
    }
    print(`lodash_findIndex: ${endTime - startTime} ms`)
}

function findLastIndex_Test() {
    const source = [
        { 'user': 'barney', 'active': false },
        { 'user': 'fred', 'active': false },
        { 'user': 'pebbles', 'active': true }
    ];
    const source1 = { 'user': 'barney', 'active': false }
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.findLastIndex(source, source1)
    }
    let endTime = Date.now();
    if (result != 0) {
        throw 'Array.findLastIndex error'
    }
    print(`lodash_findLastIndex: ${endTime - startTime} ms`)
}

function head_Test() {
    const source = [1, 2, 3, 4, 5, '6', 7, 8, 9, '10']
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 100000; i++) {
        result = lodash.head(source)
    }
    let endTime = Date.now();
    if (result != 1) {
        throw 'Array.head error'
    }
    print(`lodash_head: ${endTime - startTime} ms`)
}

function flatten_Test() {
    const source = [[1, 2], [3, 4], [5, 6]];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.flatten(source)
    }
    let endTime = Date.now();
    if (result.length != 6) {
        throw 'Array.flatten error'
    }
    print(`lodash_flatten: ${endTime - startTime} ms`)
}

function flattenDeep_Test() {
    const source = [1, [2, [3, [4]], 5]];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.flattenDeep(source)
    }
    let endTime = Date.now();
    if (result.length != 5) {
        throw 'Array.flattenDeep error'
    }
    print(`lodash_flattenDeep: ${endTime - startTime} ms`)
}

function flattenDepth_Test() {
    var source = [1, [2, [3, [4]], 5]];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.flattenDepth(source, 1)
    }
    let endTime = Date.now();
    if (result.length != 4) {
        throw 'Array.flattenDepth error'
    }
    print(`lodash_flattenDepth: ${endTime - startTime} ms`)
}

function fromPairs_Test() {
    var source = [['a', 1], ['b', 2], ['c', 3], ['d', 4]];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.fromPairs(source)
    }
    let endTime = Date.now();
    if (result.a != 1) {
        throw 'Array.fromPairs error'
    }
    print(`lodash_fromPairs: ${endTime - startTime} ms`)
}

function indexOf_Test() {
    var source = [1, 2, 1, 2];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.indexOf(source, 2, 2)
    }
    let endTime = Date.now();
    if (result != 3) {
        throw 'Array.indexOf error'
    }
    print(`lodash_indexOf: ${endTime - startTime} ms`)
}

function initial_Test() {
    const source = [1, 2, 3, 4, 5, '6', 7, 8, 9, '10']
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.initial(source)
    }
    let endTime = Date.now();
    if (result.length != 9) {
        throw 'Array.initial error'
    }
    print(`lodash_initial: ${endTime - startTime} ms`)
}

function intersection_Test() {
    const source = [1, 2, 3, 4, 5, '6', 7, 8, 9, '10']
    const source1 = [2, 3, 4]
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.intersection(source, source1)
    }
    let endTime = Date.now();
    if (result.length != 3) {
        throw 'Array.intersection error'
    }
    print(`lodash_intersection: ${endTime - startTime} ms`)
}

function intersectionBy_Test() {
    const source = [2.1, 1.2, 2.3, 3.4, 4.5]
    const source1 = [2.2, 3.2]
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.intersectionBy(source, source1, Math.floor)
    }
    let endTime = Date.now();
    if (result.length != 2) {
        throw 'Array.intersectionBy error'
    }
    print(`lodash_intersectionBy: ${endTime - startTime} ms`)
}

function intersectionWith_Test() {
    const source = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
    const source1 = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.intersectionWith(source, source1, lodash.isEqual)
    }
    let endTime = Date.now();
    if (result[0].y != 2) {
        throw 'Array.intersectionWith error'
    }
    print(`lodash_intersectionWith: ${endTime - startTime} ms`)
}

function join_Test() {
    const source = ['a', 'b', 'c', 'd'];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.join(source, '~')
    }
    let endTime = Date.now();
    if (result != 'a~b~c~d') {
        throw 'Array.join error'
    }
    print(`lodash_join: ${endTime - startTime} ms`)
}

function last_Test() {
    const source = [1, 2, 3, 4, 5, '6', 7, 8, 9, '10']
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 100000; i++) {
        result = lodash.last(source)
    }
    let endTime = Date.now();
    if (result != '10') {
        throw 'Array.last error'
    }
    print(`lodash_last: ${endTime - startTime} ms`)
}

function lastIndexOf_Test() {
    const source = [1, 2, 3, 4, 5, '6', 7, 8, 9, '10']
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.lastIndexOf(source, 3, 2)
    }
    let endTime = Date.now();
    if (result != 2) {
        throw 'Array.lastIndexOf error'
    }
    print(`lodash_lastIndexOf: ${endTime - startTime} ms`)
}

function nth_Test() {
    const source = [1, 2, 3, 4, 5, '6', 7, 8, 9, '10']
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.nth(source, -2)
    }
    let endTime = Date.now();
    if (result != 9) {
        throw 'Array.nth error'
    }
    print(`lodash_nth: ${endTime - startTime} ms`)
}

function pull_Test() {
    const source = [1, 2, 3, 4, 5, '6', 7, 8, 9, '10']
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.pull(source, 1, 2)
    }
    let endTime = Date.now();
    if (result.length != 8) {
        throw 'Array.pull error'
    }
    print(`lodash_pull: ${endTime - startTime} ms`)
}

function pullAll_Test() {
    const source = ['a', 'b', 'c', 'a', 'b', 'c']
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.pullAll(source, ['a', 'c'])
    }
    let endTime = Date.now();
    if (result.length != 2) {
        throw 'Array.pullAll error'
    }
    print(`lodash_pullAll: ${endTime - startTime} ms`)
}

function pullAllBy_Test() {
    const source = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.pullAllBy(source, [{ 'x': 1 }, { 'x': 3 }], 'x')
    }
    let endTime = Date.now();
    if (result[0].x != 2) {
        throw 'Array.pullAllBy error'
    }
    print(`lodash_pullAllBy: ${endTime - startTime} ms`)
}

function pullAllWith_Test() {
    const source = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.pullAllWith(source, [{ 'x': 3, 'y': 4 }], lodash.isEqual)
    }
    let endTime = Date.now();
    if (result[0].y != 2) {
        throw 'Array.pullAllWith error'
    }
    print(`lodash_pullAllWith: ${endTime - startTime} ms`)
}

function pullAt_Test() {
    // const source = ['a', 'b', 'c', 'd'];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        const source = ['a', 'b', 'c', 'd'];
        result = lodash.pullAt(source, [1, 3])
    }
    let endTime = Date.now();
    if (result[0] != 'b') {
        throw 'Array.pullAt error'
    }
    print(`lodash_pullAt: ${endTime - startTime} ms`)
}

function remove_Test() {
    // const source = ['a', 'b', 'c', 'd'];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        const source = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        result = lodash.remove(source, function (n) {
            return n % 3 == 0;
        })
    }
    let endTime = Date.now();
    if (result[0] != 3) {
        throw 'Array.remove error'
    }
    print(`lodash_remove: ${endTime - startTime} ms`)
}

function reverse_Test() {
    const source = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 100000; i++) {
        result = lodash.reverse(source)
    }
    let endTime = Date.now();
    if (result[0] != 'a') {
        throw 'Array.reverse error'
    }
    print(`lodash_reverse: ${endTime - startTime} ms`)
}

function slice_Test() {
    const source = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.slice(source, 0, 3)
    }
    let endTime = Date.now();
    if (result.length != 3) {
        throw 'Array.slice error'
    }
    print(`lodash_slice: ${endTime - startTime} ms`)
}

function sortedIndex_Test() {
    const source = [1, 3, 4, 5, 8];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.sortedIndex(source, 7)
    }
    let endTime = Date.now();
    if (result != 4) {
        throw 'Array.sortedIndex error'
    }
    print(`lodash_sortedIndex: ${endTime - startTime} ms`)
}

function sortedIndexBy_Test() {
    const source = [{ 'x': 4 }, { 'x': 5 }];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.sortedIndexBy(source, { 'x': 4 }, function (o) { return o.x })
    }
    let endTime = Date.now();
    if (result != 0) {
        throw 'Array.sortedIndexBy error'
    }
    print(`lodash_sortedIndexBy: ${endTime - startTime} ms`)
}

function sortedIndexOf_Test() {
    const source = [4, 5, 5, 5, 6, 7, 8, 9, 10];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.sortedIndexOf(source, 5)
    }
    let endTime = Date.now();
    if (result != 1) {
        throw 'Array.sortedIndexOf error'
    }
    print(`lodash_sortedIndexOf: ${endTime - startTime} ms`)
}

function sortedLastIndex_Test() {
    const source = [4, 5, 5, 5, 6, 7, 8, 9, 10];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.sortedLastIndex(source, 5)
    }
    let endTime = Date.now();
    if (result != 4) {
        throw 'Array.sortedLastIndex error'
    }
    print(`lodash_sortedLastIndex: ${endTime - startTime} ms`)
}

function sortedLastIndexBy_Test() {
    const source = [{ 'x': 4 }, { 'x': 5 }];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.sortedLastIndexBy(source, { 'x': 4 }, function (o) { return o.x })
    }
    let endTime = Date.now();
    if (result != 1) {
        throw 'Array.sortedLastIndexBy error'
    }
    print(`lodash_sortedLastIndexBy: ${endTime - startTime} ms`)
}

function sortedLastIndexOf_Test() {
    const source = [4, 5, 5, 5, 6, 7, 8, 9, 10];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.sortedLastIndexOf(source, 5)
    }
    let endTime = Date.now();
    if (result != 3) {
        throw 'Array.sortedLastIndexOf error'
    }
    print(`lodash_sortedLastIndexOf: ${endTime - startTime} ms`)
}

function sortedUniq_Test() {
    const source = [4, 5, 5, 5, 6, 7, 8, 9, 10];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.sortedUniq(source)
    }
    let endTime = Date.now();
    if (result.length != 7) {
        throw 'Array.sortedUniq error'
    }
    print(`lodash_sortedUniq: ${endTime - startTime} ms`)
}

function sortedUniqBy_Test() {
    const source = [1.1, 1.2, 2.3, 2.4];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.sortedUniqBy(source, Math.floor)
    }
    let endTime = Date.now();
    if (result.length != 2) {
        throw 'Array.sortedUniqBy error'
    }
    print(`lodash_sortedUniqBy: ${endTime - startTime} ms`)
}

function tail_Test() {
    const source = [1, 2, 3, 4, 5];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.tail(source)
    }
    let endTime = Date.now();
    if (result[0] != 2) {
        throw 'Array.tail error'
    }
    print(`lodash_tail: ${endTime - startTime} ms`)
}

function take_Test() {
    const source = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.take(source, 2)
    }
    let endTime = Date.now();
    if (result.length != 2) {
        throw 'Array.take error'
    }
    print(`lodash_take: ${endTime - startTime} ms`)
}

function takeRight_Test() {
    const source = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.takeRight(source, 3)
    }
    let endTime = Date.now();
    if (result[0] != 8) {
        throw 'Array.takeRight error'
    }
    print(`lodash_takeRight: ${endTime - startTime} ms`)
}

function takeRightWhile_Test() {
    const source = [
        { 'user': 'barney', 'active': true },
        { 'user': 'fred', 'active': false },
        { 'user': 'pebbles', 'active': false }
    ];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.takeRightWhile(source, function (o) { return !o.active; });
    }
    let endTime = Date.now();
    if (result[0].user != 'fred') {
        throw 'Array.takeRightWhile error'
    }
    print(`lodash_takeRightWhile: ${endTime - startTime} ms`)
}

function takeWhile_Test() {
    const source = [
        { 'user': 'barney', 'active': false },
        { 'user': 'fred', 'active': false },
        { 'user': 'pebbles', 'active': true }
    ];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.takeWhile(source, function (o) { return !o.active; });
    }
    let endTime = Date.now();
    if (result[0].user != 'barney') {
        throw 'Array.takeWhile error'
    }
    print(`lodash_takeWhile: ${endTime - startTime} ms`)
}

function union_Test() {
    const source = [1, 3, 4, 6, 7, 8, 9, 10];
    const source1 = [2, 4, 5, 7, 9, 11, 12]
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.union(source, source1)
    }
    let endTime = Date.now();
    if (result.length != 12) {
        throw 'Array.union error'
    }
    print(`lodash_union: ${endTime - startTime} ms`)
}

function unionBy_Test() {
    const source = [1.1, 3.1, 4.2, 6.4, 7.3, 8.2, 9.7, 10.12];
    const source1 = [2.2, 4.2, 5.3, 7.4, 9.5, 11.8, 12.6]
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.unionBy(source, source1, Math.floor)
    }
    let endTime = Date.now();
    if (result.length != 12) {
        throw 'Array.unionBy error'
    }
    print(`lodash_unionBy: ${endTime - startTime} ms`)
}

function unionWith_Test() {
    const source = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
    const source1 = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.unionWith(source, source1, lodash.isEqual)
    }
    let endTime = Date.now();
    if (result.length != 3) {
        throw 'Array.unionWith error'
    }
    print(`lodash_unionWith: ${endTime - startTime} ms`)
}

function uniq_Test() {
    const source = [1, 3, 4, 6, 7, 8, 9, 10, 2, 4, 5, 8];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 100000; i++) {
        result = lodash.uniq(source)
    }
    let endTime = Date.now();
    if (result.length != 10) {
        throw 'Array.uniq error'
    }
    print(`lodash_uniq: ${endTime - startTime} ms`)
}

function uniqBy_Test() {
    const source = [1.1, 3.1, 4.2, 6.4, 7.3, 8.2, 9.7, 10.12, 2.2, 4.2, 5.3, 7.4, 9.5,];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.uniqBy(source, Math.floor)
    }
    let endTime = Date.now();
    if (result.length != 10) {
        throw 'Array.uniqBy error'
    }
    print(`lodash_uniqBy: ${endTime - startTime} ms`)
}

function uniqWith_Test() {
    const source = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.uniqWith(source, lodash.isEqual)
    }
    let endTime = Date.now();
    if (result.length != 3) {
        throw 'Array.uniqWith error'
    }
    print(`lodash_uniqWith: ${endTime - startTime} ms`)
}

function unzip_Test() {
    const zipped = lodash.zip(['a', 'b'], [1, 2], [true, false]);
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.unzip(zipped)
    }
    let endTime = Date.now();
    if (result.length != 3) {
        throw 'Array.unzip error'
    }
    print(`lodash_unzip: ${endTime - startTime} ms`)
}

function unzipWith_Test() {
    const zipped = lodash.zip([1, 2], [10, 20], [100, 200]);
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.unzipWith(zipped, lodash.add)
    }
    let endTime = Date.now();
    if (result[2] != 300) {
        throw 'Array.unzipWith error'
    }
    print(`lodash_unzipWith: ${endTime - startTime} ms`)
}

function without_Test() {
    const source = [2, 1, 2, 3]
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.without(source, 1, 2)
    }
    let endTime = Date.now();
    if (result[0] != 3) {
        throw 'Array.without error'
    }
    print(`lodash_without: ${endTime - startTime} ms`)
}

function xor_Test() {
    const source = [2, 1]
    const source1 = [2, 3]
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.xor(source, source1)
    }
    let endTime = Date.now();
    if (result[1] != 3) {
        throw 'Array.xor error'
    }
    print(`lodash_xor: ${endTime - startTime} ms`)
}

function xorBy_Test() {
    const source = [2.1, 1.2]
    const source1 = [2.3, 3.4]
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.xorBy(source, source1, Math.floor)
    }
    let endTime = Date.now();
    if (result[1] != 3.4) {
        throw 'Array.xorBy error'
    }
    print(`lodash_xorBy: ${endTime - startTime} ms`)
}

function xorWith_Test() {
    const source = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
    const source1 = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.xorWith(source, source1, lodash.isEqual)
    }
    let endTime = Date.now();
    if (result[1].x != 1) {
        throw 'Array.xorWith error'
    }
    print(`lodash_xorWith: ${endTime - startTime} ms`)
}


function zip_Test() {
    const source = ['a', 'b', 'c'];
    const source1 = [1, 2, 3];
    const source2 = [true, false, true];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.zip(source, source1, source2)
    }
    let endTime = Date.now();
    if (result.length != 3) {
        throw 'Array.zip error'
    }
    print(`lodash_zip: ${endTime - startTime} ms`)
}

function zipObject_Test() {
    const source = ['a', 'b', 'c'];
    const source1 = [1, 2, 3];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.zipObject(source, source1)
    }
    let endTime = Date.now();
    if (result.a != 1) {
        throw 'Array.zipObject error'
    }
    print(`lodash_zipObject: ${endTime - startTime} ms`)
}

function zipObjectDeep_Test() {
    const source = ['a.b[0].c', 'a.b[1].d'];
    const source1 = [1, 2];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.zipObjectDeep(source, source1)
    }
    let endTime = Date.now();
    if (result.a.b[0].c != 1) {
        throw 'Array.zipObjectDeep error'
    }
    print(`lodash_zipObjectDeep: ${endTime - startTime} ms`)
}

function zipWith_Test() {
    const source = [1, 2];
    const source1 = [10, 20];
    const source2 = [100, 200];
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.zipWith(source, source1, source2, function (a, b, c) { return a + b + c })
    }
    let endTime = Date.now();
    if (result[1] != 222) {
        throw 'Array.zipWith error'
    }
    print(`lodash_zipWith: ${endTime - startTime} ms`)
}

function lodash_Array_Test() {
    chunk_Test()
    compact_Test()
    concat_Test()
    difference_Test()
    differenceBy_Test()
    differenceWith_Test()
    drop_Test()
    dropRight_Test()
    dropRightWhile_Test()
    dropWhile_Test()
    fill_Test()
    findIndex_Test()
    findLastIndex_Test()
    head_Test()
    flatten_Test()
    flattenDeep_Test()
    flattenDepth_Test()
    fromPairs_Test()
    indexOf_Test()
    initial_Test()
    intersection_Test()
    intersectionBy_Test()
    intersectionWith_Test()
    join_Test()
    last_Test()
    lastIndexOf_Test()
    nth_Test()
    pull_Test()
    pullAll_Test()
    pullAllBy_Test()
    pullAllWith_Test()
    pullAt_Test()
    remove_Test()
    reverse_Test()
    slice_Test()
    sortedIndex_Test()
    sortedIndexBy_Test()
    sortedIndexOf_Test()
    sortedLastIndex_Test()
    sortedLastIndexBy_Test()
    sortedLastIndexOf_Test()
    sortedUniq_Test()
    sortedUniqBy_Test()
    tail_Test()
    take_Test()
    takeRight_Test()
    takeRightWhile_Test()
    takeWhile_Test()
    union_Test()
    unionBy_Test()
    unionWith_Test()
    uniq_Test()
    uniqBy_Test()
    uniqWith_Test()
    unzip_Test()
    unzipWith_Test()
    without_Test()
    xor_Test()
    xorBy_Test()
    xorWith_Test()
    zip_Test()
    zipObject_Test()
    zipObjectDeep_Test()
    zipWith_Test()
}

// String

function camelCase_Test() {
    const source = '__FOO_BAR__';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.camelCase(source)
    }
    let endTime = Date.now();
    if (result != 'fooBar') {
        throw 'String.camelCase error'
    }
    print(`lodash_camelCase: ${endTime - startTime} ms`)
}

function capitalize_Test() {
    const source = 'FRED IS A TYPE BODY So Much COLLSS';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.capitalize(source)
    }
    let endTime = Date.now();
    if (result != 'Fred is a type body so much collss') {
        throw 'String.capitalize error'
    }
    print(`lodash_capitalize: ${endTime - startTime} ms`)
}

function deburr_Test() {
    const source = 'déjà vu';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.deburr(source)
    }
    let endTime = Date.now();
    if (result != 'deja vu') {
        throw 'String.deburr error'
    }
    print(`lodash_deburr: ${endTime - startTime} ms`)
}


function endsWith_Test() {
    const source = 'abcdEFG';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.endsWith(source, 'b', 2)
    }
    let endTime = Date.now();
    if (result != true) {
        throw 'String.endsWith error'
    }
    print(`lodash_endsWith: ${endTime - startTime} ms`)
}

function escape_Test() {
    const source = 'fred, barney, & pebbles';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.escape(source)
    }
    let endTime = Date.now();
    if (result != 'fred, barney, &amp; pebbles') {
        throw 'String.escape error'
    }
    print(`lodash_escape: ${endTime - startTime} ms`)
}

function escapeRegExp_Test() {
    const source = '[lodash](https://lodash.com/)';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 100000; i++) {
        result = lodash.escapeRegExp(source)
    }
    let endTime = Date.now();
    if (result == null) {
        throw 'String.escapeRegExp error'
    }
    print(`lodash_escapeRegExp: ${endTime - startTime} ms`)
}


function kebabCase_Test() {
    const source = '__FOO_BAR__HUAWEI_WORLD';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.kebabCase(source)
    }
    let endTime = Date.now();
    if (result != 'foo-bar-huawei-world') {
        throw 'String.kebabCase error'
    }
    print(`lodash_kebabCase: ${endTime - startTime} ms`)
}

function lowerCase_Test() {
    const source = '__FOO_BAR__HUAWEI_WORLD';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.lowerCase(source)
    }
    let endTime = Date.now();
    if (result != 'foo bar huawei world') {
        throw 'String.lowerCase error'
    }
    print(`lodash_lowerCase: ${endTime - startTime} ms`)
}

function lowerFirst_Test() {
    const source = 'FOO_BAR__HUAWEI_WORLD';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.lowerFirst(source)
    }
    let endTime = Date.now();
    if (result != 'fOO_BAR__HUAWEI_WORLD') {
        throw 'String.lowerFirst error'
    }
    print(`lodash_lowerFirst: ${endTime - startTime} ms`)
}

function pad_Test() {
    const source = 'world';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.pad(source, 8, '_-')
    }
    let endTime = Date.now();
    if (result.length != 8) {
        throw 'String.pad error'
    }
    print(`lodash_pad: ${endTime - startTime} ms`)
}

function padEnd_Test() {
    const source = 'world';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.padEnd(source, 18, '_-')
    }
    let endTime = Date.now();
    if (result.length != 18) {
        throw 'String.padEnd error'
    }
    print(`lodash_padEnd: ${endTime - startTime} ms`)
}

function padStart_Test() {
    const source = 'world';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.padStart(source, 18, '_-')
    }
    let endTime = Date.now();
    if (result.length != 18) {
        throw 'String.padStart error'
    }
    print(`lodash_padStart: ${endTime - startTime} ms`)
}

function parseInt_Test() {
    const source = '091World3212';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 100000; i++) {
        result = lodash.parseInt(source, 18, '_-')
    }
    let endTime = Date.now();
    if (result != 91) {
        throw 'String.parseInt error'
    }
    print(`lodash_parseInt: ${endTime - startTime} ms`)
}

function repeat_Test() {
    const source = 'HUAWEI';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.repeat(source, 10)
    }
    let endTime = Date.now();
    if (result.length != 60) {
        throw 'String.repeat error'
    }
    print(`lodash_repeat: ${endTime - startTime} ms`)
}

function replace_Test() {
    const source = 'Hello Fred';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 100000; i++) {
        result = lodash.replace(source, 'Fred', 'Barney')
    }
    let endTime = Date.now();
    if (result != 'Hello Barney') {
        throw 'String.replace error'
    }
    print(`lodash_replace: ${endTime - startTime} ms`)
}

function snakeCase_Test() {
    const source = 'Hello Fred Is A Big Ball';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.snakeCase(source, 'Fred', 'Barney')
    }
    let endTime = Date.now();
    if (result != 'hello_fred_is_a_big_ball') {
        throw 'String.snakeCase error'
    }
    print(`lodash_snakeCase: ${endTime - startTime} ms`)
}

function split_Test() {
    const source = 'hello_fred_is_a_big_ball';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.split(source, '_', '2')
    }
    let endTime = Date.now();
    if (result.length != 2) {
        throw 'String.split error'
    }
    print(`lodash_split: ${endTime - startTime} ms`)
}

function startCase_Test() {
    const source = 'hello_fred_is_a_big_ball';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.startCase(source, '_', '2')
    }
    let endTime = Date.now();
    if (result != 'Hello Fred Is A Big Ball') {
        throw 'String.startCase error'
    }
    print(`lodash_startCase: ${endTime - startTime} ms`)
}

function startsWith_Test() {
    const source = 'hello_fred_is_a_big_ball';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.startsWith(source, '_', 5)
    }
    let endTime = Date.now();
    if (result != true) {
        throw 'String.startsWith error'
    }
    print(`lodash_startsWith: ${endTime - startTime} ms`)
}

function toLower_Test() {
    const source = 'HELLO_FRED_IS_A_BIG_BALL';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 100000; i++) {
        result = lodash.toLower(source)
    }
    let endTime = Date.now();
    if (result != 'hello_fred_is_a_big_ball') {
        throw 'String.toLower error'
    }
    print(`lodash_toLower: ${endTime - startTime} ms`)
}

function toUpper_Test() {
    const source = 'hello_fred_is_a_big_ball';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 100000; i++) {
        result = lodash.toUpper(source)
    }
    let endTime = Date.now();
    if (result != 'HELLO_FRED_IS_A_BIG_BALL') {
        throw 'String.toUpper error'
    }
    print(`lodash_toUpper: ${endTime - startTime} ms`)
}

function trim_Test() {
    const source = '-_-abc-_-';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.trim(source, '_-')
    }
    let endTime = Date.now();
    if (result != 'abc') {
        throw 'String.trim error'
    }
    print(`lodash_trim: ${endTime - startTime} ms`)
}

function trimEnd_Test() {
    const source = '-_-abc-_-';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.trimEnd(source, '_-')
    }
    let endTime = Date.now();
    if (result != '-_-abc') {
        throw 'String.trimEnd error'
    }
    print(`lodash_trimEnd: ${endTime - startTime} ms`)
}

function trimStart_Test() {
    const source = '-_-abc-_-';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.trimStart(source, '_-')
    }
    let endTime = Date.now();
    if (result != 'abc-_-') {
        throw 'String.trimStart error'
    }
    print(`lodash_trimStart: ${endTime - startTime} ms`)
}

function truncate_Test() {
    const source = 'hi-diddly-ho there, neighborino';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.truncate(source, {
            length: 24,
            separator: /,? +/
        })
    }
    let endTime = Date.now();
    if (result != 'hi-diddly-ho there...') {
        throw 'String.truncate error'
    }
    print(`lodash_truncate: ${endTime - startTime} ms`)
}

function unescape_Test() {
    const source = 'fred, barney, &amp; pebbles';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.unescape(source)
    }
    let endTime = Date.now();
    if (result != 'fred, barney, & pebbles') {
        throw 'String.unescape error'
    }
    print(`lodash_unescape: ${endTime - startTime} ms`)
}

function upperCase_Test() {
    const source = 'hello_fred_is_a_big_ball';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.upperCase(source)
    }
    let endTime = Date.now();
    if (result != 'HELLO FRED IS A BIG BALL') {
        throw 'String.upperCase error'
    }
    print(`lodash_upperCase: ${endTime - startTime} ms`)
}

function upperFirst_Test() {
    const source = 'hello_fred_is_a_big_ball';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.upperFirst(source)
    }
    let endTime = Date.now();
    if (result != 'Hello_fred_is_a_big_ball') {
        throw 'String.upperFirst error'
    }
    print(`lodash_upperFirst: ${endTime - startTime} ms`)
}

function words_Test() {
    const source = 'hello_fred_is_a_big_ball';
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.words(source, /[^_ ]+/g)
    }
    let endTime = Date.now();
    if (result.length != 6) {
        throw 'String.words error'
    }
    print(`lodash_words: ${endTime - startTime} ms`)
}

function lodash_string_Test() {
    camelCase_Test()
    capitalize_Test()
    deburr_Test()
    endsWith_Test()
    escape_Test()
    escapeRegExp_Test()
    kebabCase_Test()
    lowerCase_Test()
    lowerFirst_Test()
    pad_Test()
    padEnd_Test()
    padStart_Test()
    parseInt_Test()
    repeat_Test()
    replace_Test()
    snakeCase_Test()
    split_Test()
    startCase_Test()
    startsWith_Test()
    toLower_Test()
    toUpper_Test()
    trim_Test()
    trimEnd_Test()
    trimStart_Test()
    truncate_Test()
    unescape_Test()
    upperCase_Test()
    upperFirst_Test()
    words_Test()
}

// Object -> 43

function assign_Test() {
    function Foo() {
        this.a = 1;
    }

    function Bar() {
        this.c = 3;
    }
    Foo.prototype.b = 2;
    Bar.prototype.d = 4;
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.assign({ 'a': 0 }, new Foo, new Bar)
    }
    let endTime = Date.now();
    if (result.a != 1) {
        throw 'Object.assign error'
    }
    print(`lodash_assign: ${endTime - startTime} ms`)
}

function assignIn_Test() {
    function Foo() {
        this.a = 1;
    }

    function Bar() {
        this.c = 3;
    }
    Foo.prototype.b = 2;
    Bar.prototype.d = 4;
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.assignIn({ 'a': 0 }, new Foo, new Bar)
    }
    let endTime = Date.now();
    if (result.a != 1) {
        throw 'Object.assignIn error'
    }
    print(`lodash_assignIn: ${endTime - startTime} ms`)
}

function assignInWith_Test() {
    function Foo() {
        this.a = 1;
    }

    function Bar() {
        this.c = 3;
    }
    Foo.prototype.b = 2;
    Bar.prototype.d = 4;
    Bar.prototype.a = 5;
    Bar.prototype.b = 6;
    const object = new Foo;
    const source = new Bar;
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        lodash.assignInWith(object, source, (objValue, srcValue) => objValue > srcValue ? objValue : srcValue);
    }
    let endTime = Date.now();
    if (object.a != 5) {
        throw 'Object.assignInWith error'
    }
    print(`lodash_assignInWith: ${endTime - startTime} ms`)
}

function assignWith_Test() {
    function Foo() {
        this.a = 1;
    }

    function Bar() {
        this.a = 5;
        this.c = 3;
    }
    Foo.prototype.b = 2;
    Bar.prototype.d = 4;
    Bar.prototype.a = 5;
    const object = new Foo;
    const source = new Bar;
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        lodash.assignWith(object, source, (objValue, srcValue) => objValue > srcValue ? objValue : srcValue);
    }
    let endTime = Date.now();
    if (object.a != 5) {
        throw 'Object.assignWith error'
    }
    print(`lodash_assignWith: ${endTime - startTime} ms`)
}

function at_Test() {
    var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
    let result = null;
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.at(object, ['a[0].b.c', 'a[1]']);

    }
    let endTime = Date.now();
    if (result[0] != 3) {
        throw 'Object.at error'
    }
    print(`lodash_at: ${endTime - startTime} ms`)
}

function create_Test() {
    function Shape() {
        this.x = 0;
        this.y = 0;
    }

    function Circle() {
        Shape.call(this);
    }
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        Circle.prototype = lodash.create(Shape.prototype, { 'constructor': Circle });
    }
    let endTime = Date.now();
    const circle = new Circle
    if (circle.x = 0) {
        throw 'Object.create error'
    }
    print(`lodash_create: ${endTime - startTime} ms`)
}

function defaults_Test() {
    const object = { 'a': 1 };
    const source1 = { 'b': 2 };
    const source2 = { 'a': 3, 'c': 4 };
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.defaults(object, source1, source2);
    }
    let endTime = Date.now();
    if (result.a != 1) {
        throw 'Object.defaults error'
    }
    print(`lodash_defaults: ${endTime - startTime} ms`)
}

function defaultsDeep_Test() {
    const object = { 'a': { 'b': 2 } };
    const source1 = { 'a': { 'b': 1, 'c': 3 } };
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.defaultsDeep(object, source1);
    }
    let endTime = Date.now();
    if (result.a.c != 3) {
        throw 'Object.defaultsDeep error'
    }
    print(`lodash_defaultsDeep: ${endTime - startTime} ms`)
}

function toPairs_Test() {
    function Foo() {
        this.a = 1;
        this.b = 2;
    }
    Foo.prototype.c = 3;
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.toPairs(new Foo);
    }
    let endTime = Date.now();
    if (result.length != 2) {
        throw 'Object.toPairs error'
    }
    print(`lodash_toPairs: ${endTime - startTime} ms`)
}

function toPairsIn_Test() {
    function Foo() {
        this.a = 1;
        this.b = 2;
    }
    Foo.prototype.c = 3;
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.toPairsIn(new Foo);
    }
    let endTime = Date.now();
    if (result.length != 3) {
        throw 'Object.toPairsIn error'
    }
    print(`lodash_toPairsIn: ${endTime - startTime} ms`)
}

function findKey_Test() {
    var users = {
        'barney': { 'age': 36, 'active': true },
        'fred': { 'age': 40, 'active': false },
        'pebbles': { 'age': 1, 'active': true }
    };
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.findKey(users, function (o) { return o.age < 40 });
    }
    let endTime = Date.now();
    if (result != 'barney') {
        throw 'Object.findKey error'
    }
    print(`lodash_findKey: ${endTime - startTime} ms`)
}

function findLastKey_Test() {
    var users = {
        'barney': { 'age': 36, 'active': true },
        'fred': { 'age': 40, 'active': false },
        'pebbles': { 'age': 1, 'active': true }
    };
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.findLastKey(users, function (o) { return o.age < 40 });
    }
    let endTime = Date.now();
    if (result != 'pebbles') {
        throw 'Object.findLastKey error'
    }
    print(`lodash_findLastKey: ${endTime - startTime} ms`)
}

function forIn_Test() {
    function Foo() {
        this.a = 1;
        this.b = 2;
    }
    Foo.prototype.c = 3;
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        lodash.forIn(new Foo, function (value, key) {
            result = value
        })
    }
    let endTime = Date.now();
    if (result != 3) {
        throw 'Object.forIn error'
    }
    print(`lodash_forIn: ${endTime - startTime} ms`)
}

function forInRight_Test() {
    function Foo() {
        this.a = 1;
        this.b = 2;
    }
    Foo.prototype.c = 3;
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        lodash.forInRight(new Foo, function (value, key) {
            result = value
        })
    }
    let endTime = Date.now();
    if (result != 1) {
        throw 'Object.forInRight error'
    }
    print(`lodash_forInRight: ${endTime - startTime} ms`)
}

function forOwn_Test() {
    function Foo() {
        this.a = 1;
        this.b = 2;
    }
    Foo.prototype.c = 3;
    Foo.prototype.d = 4;
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        lodash.forOwn(new Foo, function (value, key) {
            result = value
        })
    }
    let endTime = Date.now();
    if (result != 2) {
        throw 'Object.forOwn error'
    }
    print(`lodash_forOwn: ${endTime - startTime} ms`)
}

function forOwnRight_Test() {
    function Foo() {
        this.a = 1;
        this.b = 2;
    }
    Foo.prototype.c = 3;
    Foo.prototype.d = 4;
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        lodash.forOwnRight(new Foo, function (value, key) {
            result = value
        })
    }
    let endTime = Date.now();
    if (result != 1) {
        throw 'Object.forOwnRight error'
    }
    print(`lodash_forOwnRight: ${endTime - startTime} ms`)
}

function functions_Test() {
    function Foo() {
        this.a = lodash.constant('a');
        this.b = lodash.constant('b');
    }

    Foo.prototype.c = lodash.constant('c');
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.functions(new Foo)
    }
    let endTime = Date.now();
    if (result.length != 2) {
        throw 'Object.functions error'
    }
    print(`lodash_functions: ${endTime - startTime} ms`)
}

function functionsIn_Test() {
    function Foo() {
        this.a = lodash.constant('a');
        this.b = lodash.constant('b');
    }

    Foo.prototype.c = lodash.constant('c');
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.functionsIn(new Foo)
    }
    let endTime = Date.now();
    if (result.length != 3) {
        throw 'Object.functionsIn error'
    }
    print(`lodash_functionsIn: ${endTime - startTime} ms`)
}

function get_Test() {
    const object = { 'a': [{ 'b': { 'c': 3 } }] };
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.get(object, 'a[0].b.c')
    }
    let endTime = Date.now();
    if (result != 3) {
        throw 'Object.get error'
    }
    print(`lodash_get: ${endTime - startTime} ms`)
}

function has_Test() {
    const object = { 'a': [{ 'b': { 'c': 3 } }] };
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.has(object, 'a[0].b.c')
    }
    let endTime = Date.now();
    if (result != true) {
        throw 'Object.has error'
    }
    print(`lodash_has: ${endTime - startTime} ms`)
}

function hasIn_Test() {
    function Foo() {
        this.a = lodash.constant('a');
        this.b = lodash.constant('b');
    }

    Foo.prototype.c = lodash.constant('c');
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.hasIn(new Foo, 'c')
    }
    let endTime = Date.now();
    if (result != true) {
        throw 'Object.hasIn error'
    }
    print(`lodash_hasIn: ${endTime - startTime} ms`)
}

function invert_Test() {
    const object = { 'a': 1, 'b': 2, 'c': 1 };
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.invert(object)
    }
    let endTime = Date.now();
    if (result['1'] != 'c') {
        throw 'Object.invert error'
    }
    print(`lodash_invert: ${endTime - startTime} ms`)
}

function invertBy_Test() {
    const object = { 'a': 1, 'b': 2, 'c': 1 };
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.invertBy(object, function (value) {
            return 'group' + value;
        })
    }
    let endTime = Date.now();
    if (result.group1[1] != 'c') {
        throw 'Object.invertBy error'
    }
    print(`lodash_invertBy: ${endTime - startTime} ms`)
}

function invoke_Test() {
    const object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.invoke(object, 'a[0].b.c.slice', 1, 3)
    }
    let endTime = Date.now();
    if (result[1] != 3) {
        throw 'Object.invoke error'
    }
    print(`lodash_invoke: ${endTime - startTime} ms`)
}

function keys_Test() {
    function Foo() {
        this.a = 1;
        this.b = 2;
    }

    Foo.prototype.c = 3;
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.keys(new Foo)
    }
    let endTime = Date.now();
    if (result.length != 2) {
        throw 'Object.keys error'
    }
    print(`lodash_keys: ${endTime - startTime} ms`)
}

function keysIn_Test() {
    function Foo() {
        this.a = 1;
        this.b = 2;
    }

    Foo.prototype.c = 3;
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.keysIn(new Foo)
    }
    let endTime = Date.now();
    if (result.length != 3) {
        throw 'Object.keysIn error'
    }
    print(`lodash_keysIn: ${endTime - startTime} ms`)
}

function mapKeys_Test() {
    function Foo() {
        this.a = 1;
        this.b = 2;
    }
    Foo.prototype.c = 3;
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.mapKeys(new Foo, function (value, key) {
            return key + value;
        })
    }
    let endTime = Date.now();
    if (result.a1 != 1) {
        throw 'Object.mapKeys error'
    }
    print(`lodash_mapKeys: ${endTime - startTime} ms`)
}

function mapValues_Test() {
    const users = {
        'fred': { 'user': 'fred', 'age': 40 },
        'pebbles': { 'user': 'pebbles', 'age': 1 }
    };
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.mapValues(users, function (o) {
            return o.age;
        })
    }
    let endTime = Date.now();
    if (result.fred != 40) {
        throw 'Object.mapValues error'
    }
    print(`lodash_mapValues: ${endTime - startTime} ms`)
}

function merge_Test() {
    const object = {
        'a': [{ 'b': 2 }, { 'd': 4 }]
    };
    const other = {
        'a': [{ 'c': 3 }, { 'e': 5 }]
    };
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.merge(object, other)
    }
    let endTime = Date.now();
    if (result.a.length != 2) {
        throw 'Object.merge error'
    }
    print(`lodash_merge: ${endTime - startTime} ms`)
}

function mergeWith_Test() {
    function customizer(objValue, srcValue) {
        if (lodash.isArray(objValue)) {
            return objValue.concat(srcValue);
        }
    }
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        const object = { 'a': [1], 'b': [2] };
        const other = { 'a': [3], 'b': [4] };
        result = lodash.mergeWith(object, other, customizer)
    }
    let endTime = Date.now();
    if (result.a.length != 2) {
        throw 'Object.mergeWith error'
    }
    print(`lodash_mergeWith: ${endTime - startTime} ms`)
}

function omit_Test() {
    const object = { 'a': 1, 'b': '2', 'c': 3 };
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.omit(object, ['a', 'c'])
    }
    let endTime = Date.now();
    if (result.b != '2') {
        throw 'Object.omit error'
    }
    print(`lodash_omit: ${endTime - startTime} ms`)
}

function omitBy_Test() {
    const object = { 'a': 1, 'b': '2', 'c': 3 };
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.omitBy(object, lodash.isNumber)
    }
    let endTime = Date.now();
    if (result.b != '2') {
        throw 'Object.omitBy error'
    }
    print(`lodash_omitBy: ${endTime - startTime} ms`)
}

function pick_Test() {
    const object = { 'a': 1, 'b': '2', 'c': 3 };
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.pick(object, ['a', 'c'])
    }
    let endTime = Date.now();
    if (result.a != 1) {
        throw 'Object.pick error'
    }
    print(`lodash_pick: ${endTime - startTime} ms`)
}

function pickBy_Test() {
    const object = { 'a': 1, 'b': '2', 'c': 3 };
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.pickBy(object, lodash.isNumber)
    }
    let endTime = Date.now();
    if (result.c != 3) {
        throw 'Object.pickBy error'
    }
    print(`lodash_pickBy: ${endTime - startTime} ms`)
}

function result_Test() {
    const object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.result(object, 'a[0].b.c2')
    }
    let endTime = Date.now();
    if (result != 4) {
        throw 'Object.result error'
    }
    print(`lodash_result: ${endTime - startTime} ms`)
}

function set_Test() {
    const object = { 'a': [{ 'b': { 'c': 3 } }] };
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.set(object, ['x', '0', 'y', 'z'], 5)
    }
    let endTime = Date.now();
    if (result.x[0].y.z != 5) {
        throw 'Object.set error'
    }
    print(`lodash_set: ${endTime - startTime} ms`)
}

function setWith_Test() {
    let object = {};
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.setWith(object, '[0][1]', 'a', Object)
    }
    let endTime = Date.now();
    if (result['0']['1'] != 'a') {
        throw 'Object.setWith error'
    }
    print(`lodash_setWith: ${endTime - startTime} ms`)
}

function transform_Test() {
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.transform({ 'a': 1, 'b': 2, 'c': 1 }, function (result, value, key) {
            (result[value] || (result[value] = [])).push(key);
        }, {});
    }
    let endTime = Date.now();
    if (result['1'].length != 2) {
        throw 'Object.transform error'
    }
    print(`lodash_transform: ${endTime - startTime} ms`)
}

function unset_Test() {
    const object = { 'a': [{ 'b': { 'c': 7 } }] };
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.unset(object, 'a[0].b.c');
    }
    let endTime = Date.now();
    if (result != true) {
        throw 'Object.unset error'
    }
    print(`lodash_unset: ${endTime - startTime} ms`)
}

function update_Test() {
    const object = { 'a': [{ 'b': { 'c': 3 } }] };
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.update(object, 'a[0].b.c', function (n) { return 5; });
    }
    let endTime = Date.now();
    if (result.a[0].b.c != 5) {
        throw 'Object.update error'
    }
    print(`lodash_update: ${endTime - startTime} ms`)
}

function updateWith_Test() {
    const object = {};
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.updateWith(object, '[0][1]', _.constant('a'), Object);
    }
    let endTime = Date.now();
    if (result['0']['1'] != 'a') {
        throw 'Object.updateWith error'
    }
    print(`lodash_updateWith: ${endTime - startTime} ms`)
}

function values_Test() {
    function Foo() {
        this.a = 1;
        this.b = 2;
    }
    Foo.prototype.c = 3;
    Foo.prototype.d = 4;
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.values(new Foo);
    }
    let endTime = Date.now();
    if (result.length > 2) {
        throw 'Object.values error'
    }
    print(`lodash_values: ${endTime - startTime} ms`)
}

function valuesIn_Test() {
    function Foo() {
        this.a = 1;
        this.b = 2;
    }
    Foo.prototype.c = 3;
    Foo.prototype.d = 4;
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.valuesIn(new Foo);
    }
    let endTime = Date.now();
    if (result.length != 4) {
        throw 'Object.valuesIn error'
    }
    print(`lodash_valuesIn: ${endTime - startTime} ms`)
}

function lodash_Object_Test() {
    assign_Test()
    assignIn_Test()
    assignInWith_Test()
    assignWith_Test()
    at_Test()
    create_Test()
    defaults_Test()
    defaultsDeep_Test()
    toPairs_Test()
    toPairsIn_Test()
    findKey_Test()
    findLastKey_Test()
    forIn_Test()
    forInRight_Test()
    forOwn_Test()
    forOwnRight_Test()
    functions_Test()
    functionsIn_Test()
    get_Test()
    has_Test()
    hasIn_Test()
    invert_Test()
    invertBy_Test()
    invoke_Test()
    keys_Test()
    keysIn_Test()
    mapKeys_Test()
    mapValues_Test()
    merge_Test()
    mergeWith_Test()
    omit_Test()
    omitBy_Test()
    pick_Test()
    pickBy_Test()
    result_Test()
    set_Test()
    setWith_Test()
    transform_Test()
    unset_Test()
    update_Test()
    updateWith_Test()
    values_Test()
    valuesIn_Test()
}

// Math 15

function add_Test() {
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 100000; i++) {
        result = lodash.add(101, 202);
    }
    let endTime = Date.now();
    if (result != 303) {
        throw 'Object.add error'
    }
    print(`lodash_add: ${endTime - startTime} ms`)
}

function ceil_Test() {
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.ceil(303.12310234, 2);
    }
    let endTime = Date.now();
    if (result != 303.13) {
        throw 'Object.ceil error'
    }
    print(`lodash_ceil: ${endTime - startTime} ms`)
}

function divide_Test() {
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 100000; i++) {
        result = lodash.divide(10002, 2);
    }
    let endTime = Date.now();
    if (result != 5001) {
        throw 'Object.divide error'
    }
    print(`lodash_divide: ${endTime - startTime} ms`)
}

function floor_Test() {
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.floor(0.046, 2);
    }
    let endTime = Date.now();
    if (result != 0.04) {
        throw 'Object.floor error'
    }
    print(`lodash_floor: ${endTime - startTime} ms`)
}

function max_Test() {
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.max([10, 100, 1000, 10000]);
    }
    let endTime = Date.now();
    if (result != 10000) {
        throw 'Object.max error'
    }
    print(`lodash_max: ${endTime - startTime} ms`)
}

function maxBy_Test() {
    const objects = [{ 'n': 1 }, { 'n': 2 }];
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.maxBy(objects, function (o) {
            return o.n;
        });
    }
    let endTime = Date.now();
    if (result.n != 2) {
        throw 'Object.maxBy error'
    }
    print(`lodash_maxBy: ${endTime - startTime} ms`)
}

function mean_Test() {
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.mean([10, 100, 1000, 10000]);
    }
    let endTime = Date.now();
    if (result != 2777.5) {
        throw 'Object.mean error'
    }
    print(`lodash_mean: ${endTime - startTime} ms`)
}

function meanBy_Test() {
    const objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.meanBy(objects, function (o) {
            return o.n;
        });
    }
    let endTime = Date.now();
    if (result != 5) {
        throw 'Object.meanBy error'
    }
    print(`lodash_meanBy: ${endTime - startTime} ms`)
}

function min_Test() {
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.min([10, 100, 1000, 10000]);
    }
    let endTime = Date.now();
    if (result != 10) {
        throw 'Object.min error'
    }
    print(`lodash_min: ${endTime - startTime} ms`)
}

function minBy_Test() {
    const objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.minBy(objects, function (o) {
            return o.n;
        });
    }
    let endTime = Date.now();
    if (result.n != 2) {
        throw 'Object.minBy error'
    }
    print(`lodash_minBy: ${endTime - startTime} ms`)
}

function multiply_Test() {
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 100000; i++) {
        result = lodash.multiply(20, 80);
    }
    let endTime = Date.now();
    if (result != 1600) {
        throw 'Object.multiply error'
    }
    print(`lodash_multiply: ${endTime - startTime} ms`)
}

function round_Test() {
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 100000; i++) {
        result = lodash.round(4.006, 2);
    }
    let endTime = Date.now();
    if (result != 4.01) {
        throw 'Object.round error'
    }
    print(`lodash_round: ${endTime - startTime} ms`)
}

function subtract_Test() {
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 100000; i++) {
        result = lodash.subtract(8888.2, 4444.1);
    }
    let endTime = Date.now();
    if (result != 4444.1) {
        throw 'Object.subtract error'
    }
    print(`lodash_subtract: ${endTime - startTime} ms`)
}

function sum_Test() {
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.sum([4, 2, 8, 6]);
    }
    let endTime = Date.now();
    if (result != 20) {
        throw 'Object.sum error'
    }
    print(`lodash_sum: ${endTime - startTime} ms`)
}

function sumBy_Test() {
    const objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }];
    let result = null
    let startTime = Date.now();
    for (let i = 0; i < 10000; i++) {
        result = lodash.sumBy(objects, function (o) { return o.n; });
    }
    let endTime = Date.now();
    if (result != 20) {
        throw 'Object.sumBy error'
    }
    print(`lodash_sumBy: ${endTime - startTime} ms`)
}

function lodash_math_Test() {
    add_Test()
    ceil_Test()
    divide_Test()
    floor_Test()
    max_Test()
    maxBy_Test()
    mean_Test()
    meanBy_Test()
    min_Test()
    minBy_Test()
    multiply_Test()
    round_Test()
    subtract_Test()
    sum_Test()
    sumBy_Test()

}

// Function 

function after_TEST(){
    let handleClick = () => {
        return true;
    }
    let delayedClick;

    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        delayedClick = lodash.after(10000, handleClick)
    }
    let endTime = Date.now()

    let result;
    for (let i = 0; i < 10000; i++) {
        result = delayedClick();
    }
  
    if(result !== true){
      throw new Error('lodash_after Error')
    }
    print(`lodash_after: ${endTime - startTime} ms`)
}

function ary_TEST(){
    function add(a, b) {
        return a + b;
    }
    let limitedAdd;

    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        limitedAdd = lodash.ary(add, 2);
    }
    let endTime = Date.now()

    let result = limitedAdd(10, 30)
    if(result !== 40){
      throw new Error('lodash_ary Error')
    }
    print(`lodash_ary: ${endTime - startTime} ms`)
}

function before_TEST(){
    let counter = 0;
    let func = function() {
      counter++;
      return counter;
    };
    let limitedFunc;

    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        limitedFunc = lodash.before(20, func);
    }
    let endTime = Date.now()

    let result
    for (let i = 0; i < 50; i++) {
        result = limitedFunc()
    }
  
    if(result !== 19){
      throw new Error('lodash_before Error')
    }
    print(`lodash_before: ${endTime - startTime} ms`)
}

function bind_TEST(){
    function testFunction() {
        return this.message
    }
    let context = { message: ONE_KB };
    let boundFunction;

    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        boundFunction = lodash.bind(testFunction, context);
    }
    let endTime = Date.now()
    let result = boundFunction()
  
    if(result !== ONE_KB){
      throw new Error('lodash_bind Error')
    }
    print(`lodash_bind: ${endTime - startTime} ms`)
}

function bindKey_TEST(){
    let obj = {
        name: 'John',
        greet: function(greeting) {
          return (greeting + ', ' + this.name);
        }
    };
    let boundObj;

    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        boundObj  = lodash.bindKey(obj, 'greet', ['Hello']);
    }
    let endTime = Date.now()
    let result = boundObj()
  
    if(result !== 'Hello, John'){
      throw new Error('lodash_bindKey Error')
    }
    print(`lodash_bindKey: ${endTime - startTime} ms`)
}

function curry_TEST(){
    function add(a, b, c) {
        return [a, b, c];
    }
    let curriedAdd;

    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        curriedAdd = lodash.curry(add, 3);
    }
    let endTime = Date.now()

    const partialResult1 = curriedAdd(1);
    const partialResult2 = partialResult1(2);
    const finalResult = partialResult2(3);
  
    if(JSON.stringify(finalResult) !== '[1,2,3]'){
      throw new Error('lodash_curry Error')
    }
    print(`lodash_curry: ${endTime - startTime} ms`)
}

function curryRight_TEST(){
    function complexFunction(a, b, c) {
        return [a, b, c];
    }
    let curriedComplexFunction ;

    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        curriedComplexFunction = lodash.curryRight(complexFunction, 3);
    }
    let endTime = Date.now()

    const partialResult1 = curriedComplexFunction(1);
    const partialResult2 = partialResult1(2);
    const finalResult = partialResult2(3);
  
    if(JSON.stringify(finalResult) !== '[3,2,1]'){
      throw new Error('lodash_curryRight Error')
    }
    print(`lodash_curryRight: ${endTime - startTime} ms`)
}

function debounce_TEST(){
    let count = 0;
    let debouncedFunc;

    function myFunction() {
        count += 1
    }

    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        debouncedFunc = lodash.debounce(myFunction, 1000);
    }
    let endTime = Date.now()
 
    if(typeof(debouncedFunc) !== 'function'){
        throw new Error('lodash_debounce Error')
    }
    print(`lodash_debounce: ${endTime - startTime} ms`)
}

function flip_TEST(){
    function add(a, b, c, d) {
        return arguments;
    }

    let flippedAdd ;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        flippedAdd  = lodash.flip(add);
    }
    let endTime = Date.now()
    let result = flippedAdd(1, 2, 3, 4);

    if(result[0] !== 4){
        throw new Error('lodash_flip Error')
    }
    print(`lodash_flip: ${endTime - startTime} ms`)
}

function memoize_TEST(){
    function fibonacci(n) {
        if (n <= 1) {
          return n;
        }
        return fibonacci(n - 1) + fibonacci(n - 2);
    }

    let memoizedFibonacci ;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        memoizedFibonacci = lodash.memoize(fibonacci);
    }
    let endTime = Date.now()
    let result = memoizedFibonacci(20)

    if(result !== 6765){
        throw new Error('lodash_memoize Error')
    }
    print(`lodash_memoize: ${endTime - startTime} ms`)
}

function negate_TEST(){
    function isEven(num) {
        return num % 2 === 0;
    }

    let isOdd;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        isOdd = lodash.negate(isEven);
    }
    let endTime = Date.now()
    let result = isOdd(111)

    if(result !== true){
        throw new Error('lodash_negate Error')
    }
    print(`lodash_negate: ${endTime - startTime} ms`)
}

function once_TEST(){
    let count = 0;

    function incrementCounter() {
      count++;
      return count;
    }

    let incrementOnce ;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        incrementOnce  = lodash.once(incrementCounter);
    }
    let endTime = Date.now()
    let result = incrementOnce()

    if(result !== 1){
        throw new Error('lodash_once Error')
    }
    print(`lodash_once: ${endTime - startTime} ms`)
}

function overArgs_TEST(){
    function add(a, b) {
        return a + b;
    }

    // 定义转换函数
    let transforms = [
        function (x) {
            return x * 2;
        },
        function (y) {
            return y * 3;
        }
    ];

    let wrappedAdd;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        wrappedAdd = lodash.overArgs(add, transforms);
    }
    let endTime = Date.now()
    let result = wrappedAdd(5,6)

    if(result !== 28){
        throw new Error('lodash_overArgs Error')
    }
    print(`lodash_overArgs: ${endTime - startTime} ms`)
}

function partial_TEST(){
    function add(a, b) {
        return a * b;
    }

    let partialadd;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        partialadd = lodash.partial(add,[3]);
    }
    let endTime = Date.now()
    let result = partialadd(5)

    if(result !== 15){
        throw new Error('lodash_partial Error')
    }
    print(`lodash_partial: ${endTime - startTime} ms`)
}

function partialRight_TEST(){
    function add(a, b) {
        return a * b;
    }

    let partialadd;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        partialadd = lodash.partialRight(add,[5]);
    }
    let endTime = Date.now()
    let result = partialadd(3)

    if(result !== 15){
        throw new Error('lodash_partialRight Error')
    }
    print(`lodash_partialRight: ${endTime - startTime} ms`)
}

function rearg_TEST(){
    function add(a, b) {
        return a + b;
    }

    let reargAdd;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        reargAdd = lodash.rearg(add, [1, 0]);
    }
    let endTime = Date.now()
    let result = reargAdd(3, 5)
    if(result !== 8){
        throw new Error('lodash_rearg Error')
    }
    print(`lodash_rearg: ${endTime - startTime} ms`)
}

function rest_TEST(){
    function add(a, b, c) {
        a = +a;
        b = +b;
        c = +c;
        return a + b + c;
    }

    let rearrangedAdd;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        rearrangedAdd = lodash.rest(add);
    }
    let endTime = Date.now()
    let result = rearrangedAdd(4,10,50)

    if(result !== 64){
        throw new Error('lodash_rest Error')
    }
    print(`lodash_rest: ${endTime - startTime} ms`)
}

function spread_TEST(){
    function sum(a, b, c) {
        a = +a;
        b = +b;
        c = +c;
        return a + b + c;
    }

    let spreadSum;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        spreadSum = lodash.spread(sum);
    }
    let endTime = Date.now()
    let result = spreadSum([1, 2, 3])

    if(result !== 6){
        throw new Error('lodash_spread Error')
    }
    print(`lodash_spread: ${endTime - startTime} ms`)
}

function throttle_TEST(){
    let count = 0;
    function myFunction() {
        count++
        return count
    }

    let throttledFunction;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        throttledFunction = lodash.throttle(myFunction, 100);
    }
    let endTime = Date.now()

    if(typeof(throttledFunction) !== 'function'){
        throw new Error('lodash_throttle Error')
    }
    print(`lodash_throttle: ${endTime - startTime} ms`)
}

function unary_TEST(){
    function add(a, b) {
        return b ? b: a;
    }

    let unaryAdd;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        unaryAdd = lodash.unary(add);
    }
    let endTime = Date.now()

    let result= unaryAdd(3,4);

    if(result == 4){
        throw new Error('lodash_unary Error')
    }
    print(`lodash_unary: ${endTime - startTime} ms`)
}

function wrap_TEST(){
    const testValue = 5;
    const testWrapper = (x) => x * 2;

    let unaryAdd;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        unaryAdd  = lodash.wrap(testValue, testWrapper);
    }
    let endTime = Date.now()

    let result= unaryAdd();

    if(result !== 10){
        throw new Error('lodash_wrap Error')
    }
    print(`lodash_wrap: ${endTime - startTime} ms`)
}

function lodash_Function_Test(){
    after_TEST()
    ary_TEST()
    before_TEST()
    bind_TEST()
    bindKey_TEST()
    curry_TEST()
    curryRight_TEST()
    debounce_TEST()
    flip_TEST()
    memoize_TEST()
    negate_TEST()
    once_TEST()
    overArgs_TEST()
    partial_TEST()
    partialRight_TEST()
    rearg_TEST()
    rest_TEST()
    spread_TEST()
    throttle_TEST()
    unary_TEST()
    wrap_TEST()
}

// Collection 

function countBy_TEST(){
    const testArray = [1, 2, 3, 2, 1, 3, 4, 5, 4, 3, 2, 1, 3, 4, 5, 4, 4 ,5 ,3 ,2 ,4 ,5 ,1 ,1 ,1 ,2 ,5 ,3 ,1 ,4 ,4 ,2 ,5];

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result  = lodash.countBy(testArray);
    }
    let endTime = Date.now()

    if(result['1'] !== 7){
        throw new Error('lodash_countBy Error')
    }
    print(`lodash_countBy: ${endTime - startTime} ms`)
}

function forEach_TEST(){
    const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
    let results= [];
    function iteratee(value) {
        results.push(value * 2)
    }

    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        lodash.forEach(arr, iteratee);
    }
    let endTime = Date.now()

    if(results[0] !== 2){
        throw new Error('lodash_forEach Error')
    }
    print(`lodash_forEach: ${endTime - startTime} ms`)
}

function forEachRight_TEST(){
    let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
    let results= [];
    function iteratee(value) {
        results.push(value * 2)
    }

    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        lodash.forEachRight(arr, iteratee);
    }
    let endTime = Date.now()

    if(results[0] !== 40){
        throw new Error('lodash_forEachRight Error')
    }
    print(`lodash_forEachRight: ${endTime - startTime} ms`)
}

function every_TEST(){
    let testArray = [12, 15, 20, 25, 89, 45, 146, 89, 56, 15, 48, 26, 12 ,36 ,958, 78, 221, 45, 65, 98, 45, 98, 78 ,45 ,43];
    function predicateTtem(item) {
        return item > 10; 
    }
    
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.every(testArray, predicateTtem);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_every Error')
    }
    print(`lodash_every: ${endTime - startTime} ms`)
}

function filter_TEST(){
    function isEven(num) {
        return num % 2 === 0;
    }
    let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.filter(numbers, isEven);
    }
    let endTime = Date.now()

    if(result[0] !== 2){
        throw new Error('lodash_filter Error')
    }
    print(`lodash_filter: ${endTime - startTime} ms`)
}

function find_TEST(){
    let numbers = [1, 2, 3, 4, 5];
    function computeNum(num) { return num == 3; }

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.find(numbers, computeNum);
    }
    let endTime = Date.now()

    if(result !== 3){
        throw new Error('lodash_find Error')
    }
    print(`lodash_find: ${endTime - startTime} ms`)
}

function findLast_TEST(){
    let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
    function computeNum(num) { return num > 3; }

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.findLast(numbers, computeNum);
    }
    let endTime = Date.now()

    if(result !== numbers[numbers.length - 1]){
        throw new Error('lodash_findLast Error')
    }
    print(`lodash_findLast: ${endTime - startTime} ms`)
}

function flatMap_TEST(){
    let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
    function flatMapNum(num) {
        return [num, num * 2]; 
    }

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.flatMap(numbers, flatMapNum);
    }
    let endTime = Date.now()

    if(result.length !== numbers.length * 2){
        throw new Error('lodash_flatMap Error')
    }
    print(`lodash_flatMap: ${endTime - startTime} ms`)
}

function flatMapDeep_TEST(){
    let nestedArray = [1, 2, [3], [4], [5],[[6]], 7, 8, [9], 10, [11], [12], 13, [14], 15, [16], [17], [18], 19, 20];
    function flatMapDeepArray(num) { 
        return [num, num * 2]; 
    }

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.flatMapDeep(nestedArray, flatMapDeepArray);
    }
    let endTime = Date.now()

    if(result.length !== nestedArray.length * 2){
        throw new Error('lodash_flatMapDeep Error')
    }
    print(`lodash_flatMapDeep: ${endTime - startTime} ms`)
}

function flatMapDepth_TEST(){
    let nestedArray = [1, 2, [3], [4], [5],[6], 7, 8, [9], 10, [11], [[12]], 13, [14], 15, [16], [[17]], [18], 19, 20];
    function flatMapDeepArray(num) { 
        return [num, num * 2]; 
    }

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.flatMapDepth(nestedArray, flatMapDeepArray, 3);
    }
    let endTime = Date.now()

    if(result.length !== nestedArray.length * 2){
        throw new Error('lodash_flatMapDepth Error')
    }
    print(`lodash_flatMapDepth: ${endTime - startTime} ms`)
}

function groupBy_TEST(){
    const data = [
        { name: '张三', age: 20 },
        { name: '李四', age: 20 },
        { name: '王五', age: 30 },
        { name: '赵六', age: 30 },
    ];
    function groupByData (item) {
        return item.age;
    }

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.groupBy(data, groupByData);
    }
    let endTime = Date.now()

    if(Object.keys(result)[0].length !== 2){
        throw new Error('lodash_groupBy Error')
    }
    print(`lodash_groupBy: ${endTime - startTime} ms`)
}

function includes_TEST(){
    const collection = [1, 2, 3, 4, 5];
    const value = 3;
    const fromIndex1 = 2;

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.includes(collection, value, fromIndex1);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_includes Error')
    }
    print(`lodash_includes: ${endTime - startTime} ms`)
}

function invokeMap_TEST(){
    let arr = [[5, 1, 7], [3, 2, 1]]
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.invokeMap(arr, 'sort');
    }
    let endTime = Date.now()

    if(result[0][1] !== 5){
        throw new Error('lodash_invokeMap Error')
    }
    print(`lodash_invokeMap: ${endTime - startTime} ms`)
}

function keyBy_TEST(){
    const data = [
        { id: 1, name: '张三' },
        { id: 2, name: '李四' },
        { id: 3, name: '王五' },
    ];

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.keyBy(data, (item) => item.name);
    }
    let endTime = Date.now(Object.keys(result)[0])

    if(Object.keys(result)[0] !== '张三'){
        throw new Error('lodash_keyBy Error')
    }
    print(`lodash_keyBy: ${endTime - startTime} ms`)
}

function map_TEST(){
    let obj = { a: 1, b: 2, c: 3, d: 4, e: 5 };
    function iteratee(value) { 
        return value * 2; 
    }

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.map(obj, iteratee);
    }
    let endTime = Date.now()

    if(result[0] !== 2){
        throw new Error('lodash_map Error')
    }
    print(`lodash_map: ${endTime - startTime} ms`)
}

function orderBy_TEST(){
    const testCollection = [
        { name: 'Alice', age: 30 },
        { name: 'Bob', age: 25 },
        { name: 'Cathy', age: 35 },
        { name: 'David', age: 28 },
        { name: 'Eva', age: 32 },
        { name: 'Frank', age: 27 },
        { name: 'Grace', age: 31 },
        { name: 'Henry', age: 29 },
        { name: 'Ivy', age: 33 },
        { name: 'Jack', age: 34 },
        { name: 'Kate', age: 26 },
        { name: 'Liam', age: 35 },
        { name: 'Mia', age: 36 }
    ];
    
    const testIteratees = ['age'];
    const testOrders = ['asc'];

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.orderBy(testCollection, testIteratees, testOrders, false);
    }
    let endTime = Date.now()

    if(result[0].age !== 25){
        throw new Error('lodash_orderBy Error')
    }
    print(`lodash_orderBy: ${endTime - startTime} ms`)
}

function partition_TEST(){
    let testCollection = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100];
    let isEven = function (num) {
      return num % 2 === 0;
    };

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.partition(testCollection, isEven);
    }
    let endTime = Date.now()

    if(result[0].length !== 50){
        throw new Error('lodash_partition Error')
    }
    print(`lodash_partition: ${endTime - startTime} ms`)
}

function reduce_TEST(){
    let testArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100];
    let iterateeAdd = ((accumulator, currentValue) => accumulator + currentValue)

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.reduce(testArray, iterateeAdd);
    }
    let endTime = Date.now()

    if(result !== 5050){
        throw new Error('lodash_reduce Error')
    }
    print(`lodash_reduce: ${endTime - startTime} ms`)
}

function reduceRight_TEST(){
    let testArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100];
    let iterateeAdd = ((accumulator, currentValue) => accumulator + currentValue)
    
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.reduceRight(testArray, iterateeAdd);
    }
    let endTime = Date.now()

    if(result !== 5050){
        throw new Error('lodash_reduceRight Error')
    }
    print(`lodash_reduceRight: ${endTime - startTime} ms`)
}

function reject_TEST(){
    let testArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100];
    let filters = (num) => {
        num % 2 === 0
    }
    
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.reject(testArray, filters);
    }
    let endTime = Date.now()

    if(result.length !== testArray.length){
        throw new Error('lodash_reject Error')
    }
    print(`lodash_reject: ${endTime - startTime} ms`)
}

function sample_TEST(){
    let testArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100];

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.sample(testArray);
    }
    let endTime = Date.now()

    if(result == undefined){
        throw new Error('lodash_sample Error')
    }
    print(`lodash_sample: ${endTime - startTime} ms`)
}

function sampleSize_TEST(){
    let testArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100];
    const num = 10;

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.sampleSize(testArray, num);
    }
    let endTime = Date.now()

    if(result.length !== num){
        throw new Error('lodash_sampleSize Error')
    }
    print(`lodash_sampleSize: ${endTime - startTime} ms`)
}

function shuffle_TEST(){
    let testArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100];
    // 比较两个数组是否相等
    function arraysEqual(arr1, arr2) {
        if (arr1.length !== arr2.length) {
          return false;
        }
        for (let i = 0; i < arr1.length; i++) {
          if (arr1[i] !== arr2[i]) {
            return false;
          }
        }
        return true;
    }

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.shuffle(testArray);
    }
    let endTime = Date.now()

    if(arraysEqual(testArray, result)){
        throw new Error('lodash_shuffle Error')
    }
    print(`lodash_shuffle: ${endTime - startTime} ms`)
}

function size_TEST(){
    const complexObject = {
        a: 1,
        b: 'string',
        c: [1, 2, 3],
        d: { key: 'value' },
        e: new Set([1, 2, 3]),
        f: new Map([['key', 'value']]),
    };

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.size(complexObject);
    }
    let endTime = Date.now()

    if(result !== 6){
        throw new Error('lodash_size Error')
    }
    print(`lodash_size: ${endTime - startTime} ms`)
}

function some_TEST(){
    let testArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100];
    function predicate(value) {
        return value > 2;
    }

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.some(testArray, predicate);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_some Error')
    }
    print(`lodash_some: ${endTime - startTime} ms`)
}

function sortBy_TEST(){
    const testArray = [
        { name: 'Alice', age: 30 },
        { name: 'Bob', age: 25 },
        { name: 'Cathy', age: 35 },
        { name: 'David', age: 28 },
        { name: 'Eva', age: 32 },
        { name: 'Frank', age: 27 },
        { name: 'Grace', age: 31 },
        { name: 'Henry', age: 29 },
        { name: 'Ivy', age: 33 },
        { name: 'Jack', age: 34 },
        { name: 'Kate', age: 26 },
        { name: 'Liam', age: 35 },
        { name: 'Mia', age: 36 }
    ];

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.sortBy(testArray, ['age']);
    }
    let endTime = Date.now()

    if(result[0].name !== 'Bob'){
        throw new Error('lodash_sortBy Error')
    }
    print(`lodash_sortBy: ${endTime - startTime} ms`)
}

function lodash_Collection_Test(){
    countBy_TEST()
    forEach_TEST()
    forEachRight_TEST()
    every_TEST()
    filter_TEST()
    find_TEST()
    findLast_TEST()
    flatMap_TEST()
    flatMapDeep_TEST()
    flatMapDepth_TEST()
    groupBy_TEST()
    includes_TEST()
    invokeMap_TEST()
    keyBy_TEST()
    map_TEST()
    orderBy_TEST()
    partition_TEST()
    reduce_TEST()
    reduceRight_TEST()
    reject_TEST()
    sample_TEST()
    sampleSize_TEST()
    shuffle_TEST()
    size_TEST()
    some_TEST()
    sortBy_TEST()
}

// Date 
function now_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.now();
    }
    let endTime = Date.now()

    if(typeof result !== 'number'){
        throw new Error('lodash_now Error')
    }
    print(`lodash_now: ${endTime - startTime} ms`)
}

function lodash_Date_Test(){
    now_TEST()
}

// lang 

function castArray_TEST(){
    let testArray = {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10, k: 11, l: 12}
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.castArray(testArray);
    }
    let endTime = Date.now()

    if(result[0] !== testArray){
        throw new Error('lodash_castArray Error')
    }
    print(`lodash_castArray: ${endTime - startTime} ms`)
}

function clone_TEST(){
    const obj = {
        a: 1,
        b: 'string',
        c: [1, 2, 3],
        d: { e: 'nested' },
        [Symbol('sym')]: 'symbol'
    };

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.clone(obj);
    }
    let endTime = Date.now()

    if(result.d != obj.d){
        throw new Error('lodash_clone Error')
    }
    print(`lodash_clone: ${endTime - startTime} ms`)
}

function cloneDeep_TEST(){
    const obj = {
        a: 1,
        b: 'string',
        c: [1, 2, 3],
        d: { e: 'nested' },
        [Symbol('sym')]: 'symbol'
    };

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.cloneDeep(obj);
    }
    let endTime = Date.now()

    if(result.d == obj.d){
        throw new Error('lodash_cloneDeep Error')
    }
    print(`lodash_cloneDeepe: ${endTime - startTime} ms`)
}

function cloneDeepWith_TEST(){
    const obj = {
        a: 1,
        b: 'string',
        c: [1, 2, 3],
        d: { e: 'nested' },
        [Symbol('sym')]: 'symbol'
    };
    function customizer(value) {
        for (let key in value) {
            if (typeof value[key] === 'number') {
                value[key]++ ;
                return value
            }
        }
    }

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.cloneDeepWith(obj, customizer);
    }
    let endTime = Date.now()

    if(typeof result.a != 'number'){
        throw new Error('lodash_cloneDeepWith Error')
    }
    print(`lodash_cloneDeepWith: ${endTime - startTime} ms`)
}

function cloneWith_TEST(){
    const obj = {
        a: 1,
        b: 'string',
        c: [1, 2, 3],
        d: { e: 'nested' },
        [Symbol('sym')]: 'symbol'
    };
    const customizer = (value) => {
        for (let key in value) {
            if (typeof value[key] === 'number') {
                value[key]++ ;
                return value
            }
        }
    };

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.cloneWith(obj, customizer);
    }
    let endTime = Date.now()

    if(typeof result.a != 'number'){
        throw new Error('lodash_cloneWith Error')
    }
    print(`lodash_cloneWith: ${endTime - startTime} ms`)
}

function conformsTo_TEST(){
    const obj1 = { a: 1, b: 'string', c: [1, 2, 3] };
    const source1 = { a: (value) => typeof value === 'number', b: (value) => typeof value === 'string' };

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.conformsTo(obj1, source1);
    }
    let endTime = Date.now()

    if(result !== true){
        throw new Error('lodash_conformsTo Error')
    }
    print(`lodash_conformsTo: ${endTime - startTime} ms`)
}

function eq_TEST(){
    const obj1 = { a: 1, b: 'string', c: [1, 2, 3] };
    const obj4 = { a: 1, b: 'string', c: [1, 2, 3] };

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.eq(obj1, obj4);
    }
    let endTime = Date.now()

    if(result !== false){
        throw new Error('lodash_eq Error')
    }
    print(`lodash_eq: ${endTime - startTime} ms`)
}

function gt_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.gt(Number.MAX_SAFE_INTEGER, 1);
    }
    let endTime = Date.now()
    if(result == false){
        throw new Error('lodash_gt Error')
    }
    print(`lodash_gt: ${endTime - startTime} ms`)
}

function isArguments_TEST(){
    function test1() {
        return arguments;
    }

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isArguments(test1());
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isArguments Error')
    }
    print(`lodash_isArguments: ${endTime - startTime} ms`)
}

function gte_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.gte(Number.MAX_SAFE_INTEGER,Number.MAX_SAFE_INTEGER);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_gte Error')
    }
    print(`lodash_gte: ${endTime - startTime} ms`)
}

function isArray_TEST(){
    let testArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100];
    
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.isArray(testArray);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isArray Error')
    }
    print(`lodash_isArray: ${endTime - startTime} ms`)
}

function isArrayBuffer_TEST(){
    const buffer = new ArrayBuffer(1024);

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isArrayBuffer(buffer);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isArrayBuffer Error')
    }
    print(`lodash_isArrayBuffer: ${endTime - startTime} ms`)
}

function isArrayLike_TEST(){
    const arrayLike = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }];

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isArrayLike(arrayLike);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isArrayLike Error')
    }
    print(`lodash_isArrayLike: ${endTime - startTime} ms`)
}

function isArrayLikeObject_TEST(){
    const arrayLikeObject = {
        length: 3,
        0: 'a',
        1: 'b',
        2: 'c'
    };

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isArrayLikeObject(arrayLikeObject);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isArrayLikeObject Error')
    }
    print(`lodash_isArrayLikeObject: ${endTime - startTime} ms`)
}

function isBoolean_TEST(){
    const complexBoolean = new Boolean(true);

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isBoolean(complexBoolean);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isBoolean Error')
    }
    print(`lodash_isBoolean: ${endTime - startTime} ms`)
}

function isBuffer_TEST(){
    const buffer = new Uint8Array(1024)
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.isBuffer(buffer);
    }
    let endTime = Date.now()

    if(result !== false){
        throw new Error('lodash_isBuffer Error')
    }
    print(`lodash_isBuffer: ${endTime - startTime} ms`)
}

function isDate_TEST(){
    let date = new Date();
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isDate(date);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isDate Error')
    }
    print(`lodash_isDate: ${endTime - startTime} ms`)
}

function isElement_TEST(){
    let notElement = "<div></div>";

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.isElement(notElement);
    }
    let endTime = Date.now()

    if(result !== false){
        throw new Error('lodash_isElement Error')
    }
    print(`lodash_isElement: ${endTime - startTime} ms`)
}

function isEmpty_TEST(){
    let nonEmptyArray = [];

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isEmpty(nonEmptyArray);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isEmpty Error')
    }
    print(`lodash_isEmpty: ${endTime - startTime} ms`)
}

function isEqual_TEST(){
    let value = { 'a': 1 ,'b': 2, 'c': 3, 'd': 4, 'e:': 5, 'f': 6, 'g': 7, 'h': 8};
    let other = { 'a': 1 ,'b': 2, 'c': 3, 'd': 4, 'e:': 5, 'f': 6, 'g': 7, 'h': 8};

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isEqual(value, other);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isEqual Error')
    }
    print(`lodash_isEqual: ${endTime - startTime} ms`)
}

function isEqualWith_TEST(){
    function isGreeting(value) {
        return /^h(?:i|ello)$/.test(value);
    }
    
    function customizer(objValue, othValue) {
        if (isGreeting(objValue) && isGreeting(othValue)) {
            return true;
        }
    }
    let array = ['hello', 'goodbye'];
    let other = ['hi', 'goodbye'];

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isEqualWith(array, other, customizer);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isEqualWith Error')
    }
    print(`lodash_isEqualWith: ${endTime - startTime} ms`)
}

function isError_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isError(new Error());
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isError Error')
    }
    print(`lodash_isError: ${endTime - startTime} ms`)
}

function isFinite_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.isFinite(Number.MAX_VALUE);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isFinite Error')
    }
    print(`lodash_isFinite: ${endTime - startTime} ms`)
}

function isFunction_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isFunction(function() {});
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isFunction Error')
    }
    print(`lodash_isFunction: ${endTime - startTime} ms`)
}

function isInteger_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.isInteger(Number.MAX_VALUE);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isInteger Error')
    }
    print(`lodash_isInteger: ${endTime - startTime} ms`)
}

function isLength_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.isLength(Number.MAX_SAFE_INTEGER);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isLength Error')
    }
    print(`lodash_isLength: ${endTime - startTime} ms`)
}

function isMap_TEST(){
    const myMap = new Map([
        ['key1', 'value1'],
        ['key2', 'value2'],
        ['key3', 'value3'],
        ['key4', 'value4'],
        ['key5', 'value5'],
        ['key6', 'value6'],
        ['key7', 'value7'],
        ['key8', 'value8'],
        ['key9', 'value9'],
        ['key10', 'value10']
    ]);

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isMap(myMap);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isMap Error')
    }
    print(`lodash_isMap: ${endTime - startTime} ms`)
}

function isMatch_TEST(){
    let object = { 'a': 1 ,'b': 2, 'c': 3, 'd': 4, 'e:': 5, 'f': 6, 'g': 7, 'h': 8};

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isMatch(object, { 'f': 6 });
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isMatch Error')
    }
    print(`lodash_isMatch: ${endTime - startTime} ms`)
}

function isMatchWith_TEST(){
    function isGreeting(value) {
        return /^h(?:i|ello)$/.test(value);
    }
    function customizer(objValue, srcValue) {
        if (isGreeting(objValue) && isGreeting(srcValue)) {
            return true;
        }
    }
    
    let object = { 'greeting': 'hello' };
    let source = { 'greeting': 'hi' };

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isMatchWith(object, source, customizer);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isMatchWith Error')
    }
    print(`lodash_isMatchWith: ${endTime - startTime} ms`)
}

function isNaN_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isNaN(new Number(NaN));
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isNaN Error')
    }
    print(`lodash_isNaN: ${endTime - startTime} ms`)
}

function isNative_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isNative(Array.isArray);
    }
    let endTime = Date.now()
    if(result == false){
        throw new Error('lodash_isNative Error')
    }
    print(`lodash_isNative: ${endTime - startTime} ms`)
}

function isNull_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.isNull(null);
    }
    let endTime = Date.now()
    if(result == false){
        throw new Error('lodash_isNull Error')
    }
    print(`lodash_isNull: ${endTime - startTime} ms`)
}

function isNil_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.isNil(undefined);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isNil Error')
    }
    print(`lodash_isNil: ${endTime - startTime} ms`)
}

function isNumber_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.isNumber(Number.MIN_VALUE);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isNumber Error')
    }
    print(`lodash_isNumber: ${endTime - startTime} ms`)
}

function isObjectLike_TEST(){
    let test = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100];
    
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.isObjectLike(test);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isObjectLike Error')
    }
    print(`lodash_isObjectLike: ${endTime - startTime} ms`)
}

function isObject_TEST(){
    function testFunction() {
        let count = 0;
        count++;
        return count;
    }

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.isObject(testFunction);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isObject Error')
    }
    print(`lodash_isObject: ${endTime - startTime} ms`)
}

function isPlainObject_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isPlainObject(Object.create(null));
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isPlainObject Error')
    }
    print(`lodash_isPlainObject: ${endTime - startTime} ms`)
}

function isRegExp_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isRegExp(/[.*+?^${}()|[\]\\]/g);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isRegExp Error')
    }
    print(`lodash_isRegExp: ${endTime - startTime} ms`)
}

function isSafeInteger_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.isSafeInteger(Number.MAX_SAFE_INTEGER);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isSafeInteger Error')
    }
    print(`lodash_isSafeInteger: ${endTime - startTime} ms`)
}

function isSet_TEST(){
    const mySet = new Set([1, 2, 3]);

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isSet(mySet);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isSet Error')
    }
    print(`lodash_isSet: ${endTime - startTime} ms`)
}

function isString_TEST(){
    const myString = TEN_kB;

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.isString(myString);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isString Error')
    }
    print(`lodash_isString: ${endTime - startTime} ms`)
}

function isSymbol_TEST(){
    const mySymbol = Symbol(TEN_kB);

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.isSymbol(mySymbol);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isSymbol Error')
    }
    print(`lodash_isSymbol: ${endTime - startTime} ms`)
}

function isTypedArray_TEST(){
    const typedArray = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]);

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isTypedArray(typedArray);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isTypedArray Error')
    }
    print(`lodash_isTypedArray: ${endTime - startTime} ms`)
}

function isUndefined_TEST(){
    let undefinedlet;

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.isUndefined(undefinedlet);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isUndefined Error')
    }
    print(`lodash_isUndefined: ${endTime - startTime} ms`)
}

function isWeakMap_TEST(){
    let weakMap = new WeakMap();
    weakMap.set({}, "key");

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isWeakMap(weakMap);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isWeakMap Error')
    }
    print(`lodash_isWeakMap: ${endTime - startTime} ms`)
}

function isWeakSet_TEST(){
    const weakSet = new WeakSet();
    weakSet.add({}, "key");

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.isWeakSet(weakSet);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_isWeakSet Error')
    }
    print(`lodash_isWeakSet: ${endTime - startTime} ms`)
}

function lt_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.lt('apple', 'banana');
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_lt Error')
    }
    print(`lodash_lt: ${endTime - startTime} ms`)
}

function lte_TEST(){
    let arr1 = Number.MIN_SAFE_INTEGER;
    let arr2 = Number.MAX_SAFE_INTEGER;

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.lte(arr1, arr2);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_lte Error')
    }
    print(`lodash_lte: ${endTime - startTime} ms`)
}

function toArray_TEST(){
    let myArrayString = ONE_KB;

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.toArray(myArrayString);
    }
    let endTime = Date.now()

    if(result.length !== 1024){
        throw new Error('lodash_toArray Error')
    }
    print(`lodash_toArray: ${endTime - startTime} ms`)
}

function toFinite_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.toFinite(Infinity);
    }
    let endTime = Date.now()

    if(result == 0){
        throw new Error('lodash_toFinite Error')
    }
    print(`lodash_toFinite: ${endTime - startTime} ms`)
}

function toInteger_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.toInteger(ONE_KB_NUMBER_STRING);
    }
    let endTime = Date.now()

    if(result !== 1.7976931348623157e+308){
        throw new Error('lodash_toInteger Error')
    }
    print(`lodash_toInteger: ${endTime - startTime} ms`)
}

function toLength_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.toLength(Number.MAX_VALUE);
    }
    let endTime = Date.now()

    if(result !== 4294967295){
        throw new Error('lodash_toLength Error')
    }
    print(`lodash_toLength: ${endTime - startTime} ms`)
}

function toNumber_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.toNumber(Number.MIN_VALUE);
    }
    let endTime = Date.now()

    if(result !== 5e-324){
        throw new Error('lodash_toNumber Error')
    }
    print(`lodash_toNumber: ${endTime - startTime} ms`)
}

function toPlainObject_TEST(){
    let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100];
    
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100; i++) {
        result = lodash.toPlainObject(arr);
    }
    let endTime = Date.now()

    if(!Object.keys(result)){
        throw new Error('lodash_toPlainObject Error')
    }
    print(`lodash_toPlainObject: ${endTime - startTime} ms`)
}

function toSafeInteger_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.toSafeInteger(Number.MAX_VALUE);
    }
    let endTime = Date.now()
    

    if(result !== 9007199254740991){
        throw new Error('lodash_toSafeInteger Error')
    }
    print(`lodash_toSafeInteger: ${endTime - startTime} ms`)
}

function toString_TEST(){
    let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100];
    
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.toString(arr);
    }
    let endTime = Date.now()

    if(typeof(result) !== 'string'){
        throw new Error('lodash_toString Error')
    }
    print(`lodash_toString: ${endTime - startTime} ms`)
}

function lodash_lang_Test(){
    castArray_TEST()
    clone_TEST()
    cloneDeep_TEST()
    cloneDeepWith_TEST()
    cloneWith_TEST()
    conformsTo_TEST()
    eq_TEST()
    gt_TEST()
    isArguments_TEST()
    gte_TEST()
    isArray_TEST()
    isArrayBuffer_TEST()
    isArrayLike_TEST()
    isArrayLikeObject_TEST()
    isBoolean_TEST()
    isBuffer_TEST()
    isDate_TEST()
    isElement_TEST()
    isEmpty_TEST()
    isEqual_TEST()
    isEqualWith_TEST()
    isError_TEST()
    isFinite_TEST()
    isFunction_TEST()
    isInteger_TEST()
    isLength_TEST()
    isMap_TEST()
    isMatch_TEST()
    isMatchWith_TEST()
    isNaN_TEST()
    isNative_TEST()
    isNull_TEST()
    isNil_TEST()
    isNumber_TEST()
    isObjectLike_TEST()
    isObject_TEST()
    isPlainObject_TEST()
    isRegExp_TEST()
    isSafeInteger_TEST()
    isSet_TEST()
    isString_TEST()
    isSymbol_TEST()
    isTypedArray_TEST()
    isUndefined_TEST()
    isWeakMap_TEST()
    isWeakSet_TEST()
    lt_TEST()
    lte_TEST()
    toArray_TEST()
    toFinite_TEST()
    toInteger_TEST()
    toLength_TEST()
    toNumber_TEST()
    toPlainObject_TEST()
    toSafeInteger_TEST()
    toString_TEST()
}

// Number

function clamp_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.clamp(5, 1, 10);
    }
    let endTime = Date.now()

    if(result !== 5){
        throw new Error('lodash_clamp Error')
    }
    print(`lodash_clamp: ${endTime - startTime} ms`)
}

function inRange_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.inRange(10000, 1, Number.MAX_SAFE_INTEGER);
    }
    let endTime = Date.now()

    if(result == false){
        throw new Error('lodash_inRange Error')
    }
    print(`lodash_inRange: ${endTime - startTime} ms`)
}

function random_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.random(Number.MIN_VALUE, 1000, true);
    }
    let endTime = Date.now()

    if(result > 1000 || result < Number.MIN_VALUE){
        throw new Error('lodash_random Error')
    }
    print(`lodash_random: ${endTime - startTime} ms`)
}

function lodash_Number_Test(){
    clamp_TEST()
    inRange_TEST()
    random_TEST()
}

// seq

function chain_TEST(){
    let users = [
        { 'user': 'barney',  'age': 36 },
        { 'user': 'fred',    'age': 40 },
        { 'user': 'pebbles', 'age': 1 }
    ];

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.chain(users)
    }
    let endTime = Date.now()

    let results = result.sortBy('age').map(function(o) {return o.user + ' is ' + o.age;}).head().value()
    if(results !== 'pebbles is 1'){
        throw new Error('lodash_chain Error')
    }
    print(`lodash_chain: ${endTime - startTime} ms`)
}

function tap_TEST(){
    function interceptor(value) {
        return typeof(value);
    }

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.tap(TEN_kB, interceptor)
    }
    let endTime = Date.now()

    if(result !== TEN_kB){
        throw new Error('lodash_tap Error')
    }
    print(`lodash_tap: ${endTime - startTime} ms`)
}

function thru_TEST(){
    function interceptor(value) {
        return typeof(value);
    }

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.thru(TEN_kB, interceptor)
    }
    let endTime = Date.now()

    if(result !== 'string'){
        throw new Error('lodash_thru Error')
    }
    print(`lodash_thru: ${endTime - startTime} ms`)
}

function lodash_seq_Test(){
    chain_TEST()
    tap_TEST()
    thru_TEST()
}

// util

function attempt_TEST(){
    function divide(a, b) {
        return a / b;
    }

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.attempt(divide, 10, 2)
    }
    let endTime = Date.now()

    if(result !== 5){
        throw new Error('lodash_attempt Error')
    }
    print(`lodash_attempt: ${endTime - startTime} ms`)
}

function bindAll_TEST(){
    const obj = {
        name: 'John',
        greet() {
          return `Hello, ${this.name}!`;
        },
        sayGoodbye() {
          return `Goodbye, ${this.name}!`;
        }
    };

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.bindAll(obj, ['greet', 'sayGoodbye'])
    }
    let endTime = Date.now()
    let getting = result.greet()

    if(getting !== 'Hello, John!'){
        throw new Error('lodash_bindAll Error')
    }
    print(`lodash_bindAll: ${endTime - startTime} ms`)
}

function cond_TEST(){
    const isEven = (num) => num % 2 === 0;
    const isNotEven = (num) => num % 2 !== 0;
    const double = (num) => num * 2;
    const triple = (num) => num * 3;

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.cond([
            [isEven, double],
            [isNotEven, triple]
        ])
    }
    let endTime = Date.now()
    let getting = result(5)

    if(getting !== 15){
        throw new Error('lodash_cond Error')
    }
    print(`lodash_cond: ${endTime - startTime} ms`)
}

function conforms_TEST(){
    let objects = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 };

    let isConforming;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        isConforming = lodash.conforms({ 'a': function(n) { return n === 1; }, 'b': function(n) { return n > 1; } })
    }
    let endTime = Date.now()
    let result = isConforming(objects)

    if(result == false){
        throw new Error('lodash_conforms Error')
    }
    print(`lodash_conforms: ${endTime - startTime} ms`)
}

function constant_TEST(){
    const constantValue = ONE_KB;

    let result ;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.constant(constantValue)
    }
    let endTime = Date.now()
    let getConstant = result()

    if(getConstant !== ONE_KB){
        throw new Error('lodash_constant Error')
    }
    print(`lodash_constant: ${endTime - startTime} ms`)
}

function defaultTo_TEST(){
    const defaultValue = TEN_kB;

    let result ;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.defaultTo(null, defaultValue)
    }
    let endTime = Date.now()

    if(result !== TEN_kB){
        throw new Error('lodash_defaultTo Error')
    }
    print(`lodash_defaultTo: ${endTime - startTime} ms`)
}

function flow_TEST(){
    function add(x, y) {
        return x + y;
    }
    function multiply(z) {
        return z * 10;
    }
    function square(n) {
        return n * n;
    }

    let result ;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.flow([add, multiply, square])
    }
    let endTime = Date.now()
    let calculate = result(2,3)

    if(calculate !== 2500){
        throw new Error('lodash_flow Error')
    }
    print(`lodash_flow: ${endTime - startTime} ms`)
}

function flowRight_TEST(){
    function square(n) {
        return n * n;
    }
    function multiply(z) {
        return z * 20;
    }
    function add(x, y) {
        return x + y;
    }
    let result ;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.flowRight([square, multiply, add])
    }
    let endTime = Date.now()
    let calculate = result(2,3)

    if(calculate !== 10000){
        throw new Error('lodash_flowRight Error')
    }
    print(`lodash_flowRight: ${endTime - startTime} ms`)
}

function identity_TEST(){
    let myString = ONE_KB;

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.identity(myString)
    }
    let endTime = Date.now()

    if(result !== ONE_KB){
        throw new Error('lodash_identity Error')
    }
    print(`lodash_identity: ${endTime - startTime} ms`)
}

function matches_TEST(){
    var objects = { 'a': 1 ,'b': 2, 'c': 3, 'd': 4, 'e:': 5, 'f': 6, 'g': 7, 'h': 8};
    let resultMatches;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        resultMatches = lodash.matches(objects)
    }
    let endTime = Date.now()
    let result = resultMatches({ 'a': 1 ,'b': 2, 'c': 3, 'd': 4, 'e:': 5, 'f': 6, 'g': 7, 'h': 8})

    if(result == false){
        throw new Error('lodash_matches Error')
    }
    print(`lodash_matches: ${endTime - startTime} ms`)
}

function matchesProperty_TEST(){
    const users = [
        { 'user': 'barney', 'age': 36, 'active': true },
        { 'user': 'fred',   'age': 40, 'active': false },
        { 'user': 'pebbles','age': 1,  'active': true }
    ];

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.matchesProperty('user', 'fred')
    }
    let endTime = Date.now()
    const barneys = lodash.filter(users, result);

    if(barneys[0].user !== 'fred'){
        throw new Error('lodash_matchesProperty Error')
    }
    print(`lodash_matchesProperty: ${endTime - startTime} ms`)
}

function method_TEST(){
    var objects = [
        { 'a': { 'b': lodash.constant(2) } },
        { 'a': { 'b': lodash.constant(1) } }
    ];

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.method('a.b')
    }
    let endTime = Date.now()
    const results = lodash.map(objects, result)
    
    if(results[0] !== 2 || results[1] !== 1 ){
        throw new Error('lodash_method Error')
    }
    print(`lodash_method: ${endTime - startTime} ms`)
}

function methodOf_TEST(){
    const obj = {
        'a': lodash.constant(ONE_KB)
    };

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.methodOf(obj)
    }
    let endTime = Date.now()
    let results =lodash.map('a', result)
    
    if(results[0] !== ONE_KB){
        throw new Error('lodash_methodOf Error')
    }
    print(`lodash_methodOf: ${endTime - startTime} ms`)
}

function mixin_TEST(){
    var source = {
        method1: function() {
          return 'This is method1';
        },
        method2: function() {
            return 'This is method2';
        }
    };
    var object = {};

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.mixin(object, source)
    }
    let endTime = Date.now()
    let results = object.method1();
    
    if(results !== 'This is method1'){
        throw new Error('lodash_mixin Error')
    }
    print(`lodash_mixin: ${endTime - startTime} ms`)
}

function noConflict_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.noConflict()
    }
    let endTime = Date.now()
    
    if(!result.noConflict){
        throw new Error('lodash_noConflict Error')
    }
    print(`lodash_noConflict: ${endTime - startTime} ms`)
}

function noop_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.noop()
    }
    let endTime = Date.now()
    
    if(result !== undefined){
        throw new Error('lodash_noop Error')
    }
    print(`lodash_noop: ${endTime - startTime} ms`)
}

function nthArg_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.nthArg(2)
    }
    let endTime = Date.now()
    let results = result(1, 2, 3, 4, 5)
    
    if(results !== 3){
        throw new Error('lodash_nthArg Error')
    }
    print(`lodash_nthArg: ${endTime - startTime} ms`)
}

function over_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.over([Math.max, Math.min]);
    }
    let endTime = Date.now()
    let results = result(1, 2, 3, 4, 5)
    
    if(results[0] !== 5){
        throw new Error('lodash_over Error')
    }
    print(`lodash_over: ${endTime - startTime} ms`)
}

function overEvery_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.overEvery([Boolean, isFinite]);
    }
    let endTime = Date.now()
    let results = result('1')
    
    if(results == false){
        throw new Error('lodash_overEvery Error')
    }
    print(`lodash_overEvery: ${endTime - startTime} ms`)
}

function runInContext_TEST(){
    const context = {
        name: 'John',
        age: 30,
        greet: function() {
            return `Hello, my name is ${this.name} and I am ${this.age} years old.`;
        }
    };

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10; i++) {
        result = lodash.runInContext(context);
    }
    let endTime = Date.now()
    
    if(!result.runInContext){
        throw new Error('lodash_runInContext Error')
    }
    print(`lodash_runInContext: ${endTime - startTime} ms`)
}

function stubArray_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.stubArray();
    }
    let endTime = Date.now()
    
    if(result.length !== 0){
        throw new Error('lodash_stubArray Error')
    }
    print(`lodash_stubArray: ${endTime - startTime} ms`)
}

function stubFalse_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.stubFalse();
    }
    let endTime = Date.now()
    
    if(result !== false){
        throw new Error('lodash_stubFalse Error')
    }
    print(`lodash_stubFalse: ${endTime - startTime} ms`)
}

function stubObject_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.stubObject();
    }
    let endTime = Date.now()
    
    if(Object.keys(result).length !== 0){
        throw new Error('lodash_stubObject Error')
    }
    print(`lodash_stubObject: ${endTime - startTime} ms`)
}

function stubString_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.stubString();
    }
    let endTime = Date.now()
    
    if(result.length !== 0){
        throw new Error('lodash_stubString Error')
    }
    print(`lodash_stubString: ${endTime - startTime} ms`)
}

function stubTrue_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.stubTrue();
    }
    let endTime = Date.now()
    
    if(result == false){
        throw new Error('lodash_stubTrue Error')
    }
    print(`lodash_stubTrue: ${endTime - startTime} ms`)
}

function times_TEST(){
    function square(n) {
        return n * n;
    }

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.times(5, square);
    }
    let endTime = Date.now()

    if(result[4] !== 16){
        throw new Error('lodash_times Error')
    }
    print(`lodash_times: ${endTime - startTime} ms`)
}

function toPath_TEST(){
    let path = 'a.b.c.d.e.f.g.h.i.j.k.l.m.n'

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.toPath(path);
    }
    let endTime = Date.now()
    
    if(result.length !== 14){
        throw new Error('lodash_toPath Error')
    }
    print(`lodash_toPath: ${endTime - startTime} ms`)
}

function uniqueId_TEST(){
    lodash.resetIdCounter();
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.uniqueId('user_');
    }
    let endTime = Date.now()
    
    if(result !== 'user_10000'){
        throw new Error('lodash_uniqueId Error')
    }
    print(`lodash_uniqueId: ${endTime - startTime} ms`)
}

function overSome_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.overSome([Boolean, isFinite]);
    }
    let endTime = Date.now()
    let results = result('1')
    
    if(results !== true){
        throw new Error('lodash_overSome Error')
    }
    print(`lodash_overSome: ${endTime - startTime} ms`)
}

function property_TEST(){
    const obj = { a: { b: { c: { d: { e: { f: { g: { h: { i: { j: { k: { l: { m: { n: 42} } } } } } } } } } } } } };

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.property('a.b.c.d.e.f.g.h.i.j.k.l.m.n');
    }
    let endTime = Date.now()
    let results = result(obj)

    if(results !== 42){
        throw new Error('lodash_property Error')
    }
    print(`lodash_property: ${endTime - startTime} ms`)
}

function propertyOf_TEST(){
    const obj = { a: { b: { c: { d: { e: { f: { g: { h: { i: { j: { k: { l: { m: { n: 42} } } } } } } } } } } } } };

    let result;
    let startTime = Date.now()
    for (let i = 0; i < 100000; i++) {
        result = lodash.propertyOf(obj);
    }
    let endTime = Date.now()
    let results = result('a.b.c.d.e.f.g.h.i.j.k.l.m.n')
    
    if(results !== 42){
        throw new Error('lodash_propertyOf Error')
    }
    print(`lodash_propertyOf: ${endTime - startTime} ms`)
}

function range_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.range(0, 100, 5);
    }
    let endTime = Date.now()
    
    if(result[0] !== 0){
        throw new Error('lodash_range Error')
    }
    print(`lodash_range: ${endTime - startTime} ms`)
}

function rangeRight_TEST(){
    let result;
    let startTime = Date.now()
    for (let i = 0; i < 10000; i++) {
        result = lodash.rangeRight(0, 100, 5);
    }
    let endTime = Date.now()
    
    if(result[0] !== 95){
        throw new Error('lodash_rangeRight Error')
    }
    print(`lodash_rangeRight: ${endTime - startTime} ms`)
}

function lodash_util_Test(){
    attempt_TEST()
    bindAll_TEST()
    cond_TEST()
    conforms_TEST()
    constant_TEST()
    defaultTo_TEST()
    flow_TEST()
    flowRight_TEST()
    identity_TEST()
    matches_TEST()
    matchesProperty_TEST()
    method_TEST()
    methodOf_TEST()
    mixin_TEST()
    noConflict_TEST()
    noop_TEST()
    nthArg_TEST()
    over_TEST()
    overEvery_TEST()
    runInContext_TEST()
    stubArray_TEST()
    stubFalse_TEST()
    stubObject_TEST()
    stubString_TEST()
    stubTrue_TEST()
    times_TEST()
    toPath_TEST()
    uniqueId_TEST()
    overSome_TEST()
    property_TEST()
    propertyOf_TEST()
    range_TEST()
    rangeRight_TEST()

}

let loopCountForPreheat = 1;
for (let i = 0; i < loopCountForPreheat; i++) {
    lodash_Array_Test()
    lodash_string_Test()
    lodash_Object_Test()
    lodash_math_Test()

    lodash_Function_Test()
    lodash_Collection_Test()
    lodash_Date_Test()
    lodash_lang_Test()
    lodash_Number_Test()
    lodash_seq_Test()
    lodash_util_Test()
}

ArkTools.waitAllJitCompileFinish();

lodash_Array_Test()
lodash_string_Test()
lodash_Object_Test()
lodash_math_Test()

lodash_Function_Test()
lodash_Collection_Test()
lodash_Date_Test()
lodash_lang_Test()
lodash_Number_Test()
lodash_seq_Test()
lodash_util_Test()